Запросить все сообщения, где мета-ключ не существует

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вместо этого, но не повезло.

Если кто-то может подсказать мне правильный способ создания запроса, подобного тому, который мне нужен, я буду признателен за это.

Спасибо!

JordanBel
источник
Какую версию WordPress вы используете?
s_ha_dum
Привет, извините за упущение. Я использую v3.5
JordanBel
Кажется, что этот тип запроса (с параметром сравнения, установленным на НЕ СУЩЕСТВУЮЩИЙ) был добавлен в 3.5, поэтому, насколько я могу видеть, он должен работать так, как есть. Это было бы легко сделать с помощью пользовательского запроса SELECT, хотя ...
Томас Бутелер
Спасибо, я постараюсь использовать выбор. Я должен узнать, какие таблицы запрашивать и как соответствовать запросу :(
JordanBel
Очень странно. Я не могу определить проблему с этим кодом, а вы используете 3.5+, поэтому я и спросил. Вы действительно просмотрели базу данных, чтобы убедиться, что ваши данные вставляются так, как вы думаете?
s_ha_dum

Ответы:

73

Я провел еще какое-то тестирование с этим, и, честно говоря, не могу найти причину, по которой это не сработает (если код выше не является просто фрагментом кода, а реальный код подходит для моих примеров ниже). Однако я обнаружил пару вещей, которые могут привести вас в правильном направлении.

1) Сам по себе этот мета-запрос является эквивалентом «colors IS NULL», то есть он вернет сообщения, для которых не задан этот ключ в таблице postmeta. Это случай, показанный выше, и он должен был сработать.

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

2) До WordPress 3.9 установка индекса 'отношение' к 'ИЛИ' изменяет это условие. Это возвращает обратное. Не спрашивай меня почему. Это особенно важно при выполнении нескольких мета-запросов. Это означает, что изначально невозможно выполнить запрос к сообщениям, у которых для ключа 'colors' установлено значение 'blue' (или что-либо еще) или не установлено вообще. Приведенный ниже запрос игнорирует первое условие и возвращает только те из них, которые соответствуют второму условию.

'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 :) Потребовалось некоторое время, чтобы добраться сюда - но теперь я хочу нажать upvote как минимум 10 раз (если бы только я мог;))
Lorem Monkey
Если я использую сравнивать 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
            ) 
i_a
источник