web-dev-qa-db-ja.com

Post-ID mysqlクエリへのタグ。タグ検索

タグベースの検索を実装しようとしています。特定のタグを指定すると、タグ付けされた投稿が検索され、検索条件に一致する投稿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クエリでそれを解決するのかわからない。多分im何かが足りない。事前にご協力いただきありがとうございます。

1
Tom Siwik

これらは通常のINの力学です - それはsetの全てにマッチするのではなく、setの中の何かにマッチします。

必要な一致の種類は、WPクエリ引数で tag_slug__and と呼ばれます。 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
Rarst