it-swarm.com.ru

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

Я пытаюсь получить запрос, чтобы получить все сообщения, в которых нет определенного 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 вместо этого, но не повезло.

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

Спасибо!

45
JordanBel

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

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

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

2) Установление индекса "отношение" к "ИЛИ", однако, меняет это условие. Это возвращает обратное. Не спрашивай меня почему. Это особенно важно при выполнении нескольких мета-запросов. Это означает, что изначально невозможно выполнить запрос к сообщениям, у которых для ключа '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.5. Может быть, это непреднамеренно, и они исправят это в будущих версиях, но может быть причина, почему это ведет себя так, и это приемлемый обходной путь.

69
Tomas Buteler

Используя пользовательский запрос, это сработало для меня:

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