Теги для запроса mysql Post-ID. Поиск по тегам


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

В настоящее время он работает только для одного тега.

$query = "SELECT DISTINCT $wpdb->posts.ID FROM $wpdb->terms
    LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->terms.term_id = $wpdb->term_taxonomy.term_id)
    LEFT JOIN $wpdb->term_relationships ON ($wpdb->terms.term_id = $wpdb->term_relationships.term_taxonomy_id)
    LEFT JOIN $wpdb->posts ON ($wpdb->term_relationships.object_id = $wpdb->posts.ID)
        WHERE $wpdb->term_taxonomy.taxonomy = 'post_tag' " . $substring;

Подстрока выглядит следующим образом:

$substring = "AND $wpdb->terms.slug IN ('tag1','tag2')"

И вот в чем проблема. Он не ищет отдельные сообщения, соответствующие всем критериям. Вместо этого он "собирает" все сообщения со всеми найденными тегами.

Для пример:

// postid1 -> tag1
// postid2 -> tag2
// postid3 -> tag1, tag2

$substring = "AND $wpdb->terms.slug IN ('tag1')"
//Output: postid1, postid3 - - - CORRECT
$substring = "AND $wpdb->terms.slug IN ('tag1','tag2')"
//Output: postid1, postid2, postid3 - - -WRONG!

//Expected: postid3

До сих пор я понятия не имею, как решить эту проблему в одном запросе mysql. Может быть, я что-то упускаю. Заранее спасибо за вашу помощь.

Author: Tom Siwik, 2011-01-22

1 answers

Это нормальная IN механика - она соответствует чему-либо в наборе, а не всему набору вместе взятому.

Тип соответствия, который вы хотите, называется tag_slug__and в аргументах запроса WP. Вы можете увидеть код, который генерирует SQL для него в источнике WP_Query->&get_posts() метод.

Результирующий SQL выглядит следующим образом:

SELECT p.ID 
FROM wp_posts p 
INNER JOIN wp_term_relationships tr ON (p.ID = tr.object_id) 
INNER JOIN wp_term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id) 
INNER JOIN wp_terms t ON (tt.term_id = t.term_id) 
WHERE tt.taxonomy = 'post_tag' 
AND t.slug IN ('is', 'filler') 
GROUP BY p.ID HAVING count(p.ID) = 2
 2
Author: Rarst, 2011-01-22 17:59:45