web-dev-qa-db-fra.com

Interroger tous les messages où une clé méta n'existe pas

J'essaie d'obtenir une requête pour récupérer tous les articles pour lesquels un meta_key spécifique n'existe pas, puis le créer.

J'ai des problèmes pour trouver ces publications, car la requête que je teste ne semble pas fonctionner.

Voici le code que j'utilise pour essayer de recevoir ces publications:

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

query_posts($args);

Cela ne retourne rien s'il n'y a pas de messages avec la clé colors, mais les renvoie ids des messages avec la clé colors chaque fois que cette clé est présente (l'inverse de ce dont j'ai besoin). J'ai essayé avec EXIST à la place mais pas de chance.

Si quelqu'un peut me conseiller sur la manière correcte de créer une requête comme celle dont j'ai besoin, je l'apprécierai.

Merci!

45
JordanBel

J'ai fait d'autres tests avec cela, et honnêtement, je ne trouve pas de raison pour que cela ne fonctionne pas (à moins que le code ci-dessus ne soit qu'un extrait et que le code réel corresponde à mes exemples ci-dessous). J'ai toutefois découvert quelques éléments qui pourraient vous conduire dans la bonne direction.

1) En elle-même, cette méta-requête est l’équivalent de "colors IS NULL", c’est-à-dire qu’elle renverra les publications qui n’ont pas cette clé définie dans la table postmeta. C'est le cas montré ci-dessus, et cela aurait dû fonctionner.

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

2) L'établissement de l'index de 'relation' avec 'OU' change cependant cette condition. Il retourne le contraire. Ne me demande pas pourquoi. Ceci est particulièrement important lorsque vous effectuez plusieurs méta-requêtes. Cela signifie qu’à l’origine, il n’est pas possible de faire une requête pour les publications dont la clé "couleurs" est définie sur "bleu" (ou autre) ou n’est pas définie du tout. La requête ci-dessous ignorera la première condition et renverra uniquement celles qui correspondent à la deuxième condition.

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

3) Cependant, nous pouvons tromper WordPress en utilisant la première condition si nous définissons la "valeur". Il n'a pas besoin d'une valeur pertinente (elle est ignorée, autant que je sache), mais il doit être défini pour que la condition NOT EXISTS ait un effet.

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

Ceci est vrai à partir de WordPress 3.5. Peut-être que ce n'est pas intentionnel et qu'ils le corrigeront dans les versions futures, mais il pourrait y avoir une raison pour que cela se comporte de cette façon, et c'est une solution de contournement viable.

69
Tomas Buteler

En utilisant une requête personnalisée, cela a fonctionné pour moi:

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
            ) 
10
i_a