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!


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.


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
            ) 
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.