カテゴリーやタグを検索出来るようにする
WordPressのサイト内検索でタグやカテゴリーを含めて検索する方法を紹介します。
デフォルトの検索対象はタイトル、抜粋からとなっています。
そこにカテゴリーやタグといったタームも含めて検索できる方法を紹介します。
クエリを変更する
カテゴリーやタグを含めた検索をする場合にはSQLのjoin句でタームのテーブルを結合する必要があります。
「wp_posts」テーブルのIDに対応させてターム名のテーブルを持ってくる必要があります。
「wp_posts」に結合する順番としては「wp_term_relationships」「wp_term_taxonomy」「wp_terms」の順になります。
「wp_posts」のIDと対応しているのは「wp_term_relationships」のobject_idです。
さらに「wp_term_relationships」のterm_taxonomy_idと「wp_term_taxonomy」のterm_taxonomy_idが対応しています。
「wp_term_taxonomy」のterm_idと「wp_terms」のterm_idが対応しています。
そして「wp_terms」のname列にターム名が入っています。
これをコードにすると以下のようになります。
「posts_join」フィルターを利用します。
add_filter( 'posts_join', function( $join, $query_obj ) {if( is_admin() || $query_obj->is_main_query() ) {return $join;}$join .= " LEFT JOIN (select object_id, term_taxonomy_id from wp_term_relationships) AS trs";$join .= " ON (wp_posts.ID = trs.object_id )";$join .= " LEFT JOIN (select term_taxonomy_id, term_id from wp_term_taxonomy) AS tt";$join .= " ON (trs.term_taxonomy_id = tt.term_taxonomy_id)";$join .= " LEFT JOIN (select term_id, name from wp_terms) AS t";$join .= " ON ( tt.term_id = t.term_id)";return $join;}, 10, 2 );
この状態では投稿IDが重複している状態ですので、重複を削除するためにDISTINCT句を入れます。
DISTINCT句には「posts_distinct」フィルターを使用します。
add_filter( 'posts_distinct', function( $distinct, $query_obj ) {if( is_admin() || $query_obj->is_main_query() ) {return $distinct;}$distinct = " DISTINCT";return $distinct;}, 10, 2);
これで準備は整いました。
後は検索で「$_GET[‘s’]」に渡された値に対して検索するためのwhere句の作成です。
今回は検索ワードのLIKE検索とします。
WHERE句には「posts_where」フィルターを使用します。
add_filter( 'posts_where', function add_where( $where, $query_obj ) {if( is_admin() || $query_obj->is_main_query() ) {return $where;}global $wpdb;$s = $query_obj->get('s');$like = '%'. $wpdb->esc_like( $s ). '%';$where .= $wpdb->prepare( " OR t.name LIKE %s", $like );return $where;}, 10, 2 );
これで検索ワードでカテゴリーやタグといったタームの検索もできます。
カテゴリーやタグなど制限をかけたい場合には「wp_term_taxonomy」テーブルを結合する際にwhere句を使用して変更してください。