Consultar todas as postagens em que a meta-chave não existe

50

Estou tentando obter uma consulta para recuperar todas as postagens onde um específico meta_keynão existe e depois criá-lo.

Estou tendo problemas para encontrar essas postagens, pois a consulta que estou testando parece não funcionar.

Aqui está o código que estou usando para tentar obter essas postagens:

$args = array(
   'posts_per_page' => 18,
   'cat'=>1955,
   'post_status'=>'publish',
   'meta_query' => array(
                  array(
                     'key' => 'colors',
                     'compare' => 'NOT EXISTS'
                  ),
   ));      

query_posts($args);

Isso não retorna nada se não houver postagens com a chave colors, mas as retornará idsdas postagens com a chave colorssempre que essa chave estiver presente (o oposto do que eu preciso). Eu tentei com em EXISTvez disso, mas sem sorte.

Se alguém puder me dar uma dica sobre a maneira correta de criar uma consulta como a que eu preciso, eu aprecio isso.

Obrigado!

JordanBel
fonte
Qual versão do WordPress você está usando?
s_ha_dum
Oi, desculpe pela omissão. Estou usando v3.5
JordanBel
Parece que esse tipo de consulta (com comparação definida como NOT EXISTS) foi adicionado na versão 3.5, portanto, deve funcionar como está, tanto quanto posso ver. Seria fácil fazê-lo através de costume consulta SELECT, embora ...
Tomas Buteler
Obrigado, vou tentar usar select. Devo aprender antes que as tabelas para consulta e como se conformar a consulta embora :(
JordanBel
Muito estranho. Não consigo identificar um problema com esse código e você está usando o 3.5+, e foi por isso que perguntei. Você realmente consultou o banco de dados para confirmar que seus dados estão sendo inseridos da maneira que você pensa que é?
s_ha_dum

Respostas:

73

Fiz mais alguns testes com isso e honestamente não consigo encontrar um motivo para não funcionar (a menos que o código acima seja apenas um trecho e o código real se encaixe nos meus exemplos abaixo). No entanto, descobri algumas coisas que podem levá-lo na direção certa.

1) Por si só, essa meta consulta é equivalente a "colors IS NULL", ou seja, retornará as postagens que não possuem essa chave definida na tabela postmeta. Este é o caso mostrado acima e deveria ter funcionado.

'meta_query' => array(
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS' // this should work...
    ),
)

2) Antes do WordPress 3.9, o estabelecimento do índice de 'relação' com 'OU' altera essa condição. Retorna o oposto. Não me pergunte o porquê. Isso é especialmente importante ao fazer várias meta consultas. Isso significa que não é possível inicialmente fazer uma consulta para postagens que tenham a chave 'cores' definida como 'azul' (ou o que seja) ou que não esteja definida. A consulta abaixo ignorará a primeira condição e retornará apenas aqueles que correspondem à segunda condição.

'meta_query' => array(
   'relation' => 'OR',
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS' // doesn't work
    ),
    array(
     'key' => 'colors',
     'value' => 'blue'
    )
)

3) No entanto, podemos enganar o WordPress usando a primeira condição, se definirmos o 'valor'. Ele não precisa de um valor relevante (é ignorado, até onde eu sei), mas precisa ser definido para que a NOT EXISTScondição tenha algum efeito.

'meta_query' => array(
   'relation' => 'OR',
    array(
     'key' => 'colors',
     'compare' => 'NOT EXISTS', // works!
     'value' => '' // This is ignored, but is necessary...
    ),
    array(
     'key' => 'colors',
     'value' => 'blue'
    )
)

Isso foi verdade até o WordPress 3.9. Se você ainda estiver usando uma versão mais antiga, esta é uma solução viável.

Tomas Buteler
fonte
Obrigado! E desculpe pelo atraso. Acabei usando uma consulta, mas testarei sua solução nas próximas horas para poder voltar e, talvez, se este trabalho pudermos ajudar outros. Eu o informarei assim que eu puder verificar. Obrigado novamente
JordanBel
Bem escrito e confirmado que a adição de um valor vazio retorna os resultados esperados. Eu diria que não é intencional, pode valer a pena dar uma olhada no trac.wordpress.org para ver se já existe um ticket, se não, isso é reproduzível.
Taylor Dewey
Agradecimentos para a grande explicação e solução para enganar WP :) Será que levar algum tempo para chegar aqui - mas agora eu quero clique upvote por pelo menos 10 vezes (Se eu pudesse;))
lorem macaco
Se eu usar comparar existe, valor, infelizmente, não é ignorado em versões mais recentes do WP (testado em 4.2.2)
Igor Jerosimić
10
O EXISTSe NOT EXISTS"bug" que exigia que você especifique um valor, foi fixado em WP 3.9
trex005
11

Usando uma consulta personalizada, isso funcionou para mim:

SELECT * FROM wp_posts as posts
            WHERE   posts.post_type     = 'post'
            AND NOT EXISTS (
              SELECT * FROM `wp_postmeta`
               WHERE `wp_postmeta`.`meta_key` = "your_meta_key"
                AND `wp_postmeta`.`post_id`=posts.ID
            ) 
I a
fonte