Запросити всі повідомлення, де не існує мета-ключа


50

Я намагаюся отримати запит, щоб отримати всі публікації, де певного meta_keyне існує, а потім створити його.

У мене виникають проблеми з пошуку цих публікацій, оскільки запит, який я тестую, здається, не працює.

Ось код, який я використовую, щоб спробувати отримати ці повідомлення:

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

query_posts($args);

Це нічого не повертає, якщо немає публікацій з ключем colors, але вони повертають їх idsдописів з ключем, colorsколи цей ключ присутній (навпаки тому, що мені потрібно). Я намагався з цим, EXISTале не пощастило.

Якщо хтось може підказати мені на правильний спосіб створення запиту, як той, який мені потрібен, я оціню його.

Дякую!


Яку версію WordPress ви використовуєте?
s_ha_dum

Привіт, вибачте за упущення. Я використовую v3.5
JordanBel

Схоже, що такий тип запиту (з набором порівняння НЕ ІСНУЄТЬСЯ) додано в 3.5, тому він повинен працювати як є, наскільки я бачу. Це було б легко за допомогою спеціального запиту SELECT, однак ...
Tomas Buteler

Дякую, я спробую використовувати select. Я повинен навчитися, до яких таблиць запитувати і як відповідати запиту, хоча :(
JordanBel

Дуже дивно. Я не можу помітити проблему з цим кодом, і ви використовуєте версію 3.5+, саме тому я запитав. Ви насправді переглянули базу даних, щоб підтвердити, що ваші дані вставляються так, як ви думаєте?
s_ha_dum

Відповіді:


73

Я зробив ще кілька тестувань з цим, і, чесно кажучи, не можу знайти причину, що це не спрацює (якщо тільки вищевказаний код не є просто фрагментом і реальний код підходить для моїх прикладів нижче). Проте я виявив пару речей, які можуть привести вас у правильному напрямку.

1) Сам по собі цей мета-запит є еквівалентом "кольори NULL", тобто він повертає повідомлення, у яких не встановлено цей ключ у таблиці postmeta. Це випадок, показаний вище, і він мав би спрацювати.

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

2) До WordPress 3.9, встановлення індексу 'відношення' до 'АБО' змінює цю умову. Це повертає навпаки. Не питайте мене, чому. Це особливо важливо при виконанні декількох мета-запитів. Це означає, що спочатку неможливо виконати запит на повідомлення, у яких для клавіш 'кольори' встановлено значення 'синій' (або будь-що) або взагалі не встановлено. Запит нижче буде ігнорувати першу умову і повертатиме лише ті, які відповідають другій умові.

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

3) Однак ми можемо обдурити WordPress використовувати першу умову, якщо встановити "значення". Він не потребує відповідного значення (наскільки я знаю) воно ігнорується, але його потрібно встановити для того, щоб NOT EXISTSумова мала будь-який ефект.

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

Це було дійсно до WordPress 3.9. Якщо ви все ще використовуєте старішу версію, це життєздатне рішення.


Дякую! І вибачте за затримку. Я в кінцевому підсумку використовував запит, але я буду перевіряти ваше рішення протягом наступних годин, щоб я міг переключитися назад, і, можливо, якщо у цій роботі ми допоможемо іншим. Я дам вам знати, як тільки я зможу це перевірити. Ще раз
дякую

Добре написано та підтверджено, що додавання порожнього значення повертає очікувані результати. Я б сказав, що це ненавмисно, можливо, варто поглянути на trac.wordpress.org, щоб побачити, чи вже є квиток, якщо ні - це можна відтворити.
Тейлор Дьюї

Дякую за чудове пояснення та рішення хитрості WP :) Потрапив сюди трохи часу - але тепер я хочу натиснути на принаймні 10 разів (якби тільки міг;))
мавпа lorem

Якщо я використовую порівняння EXISTS, значення, на жаль, не ігнорується в новіших версіях WP (тестовано в 4.2.2)
Ігор Єросиміч

10
Значення EXISTSта NOT EXISTS"помилка", яка вимагала від вас вказати значення, було зафіксовано в WP 3.9
trex005

11

Використовуючи спеціальний запит, для мене це спрацювало:

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
            ) 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.