2020-11-22/2023-05-23

カテゴリーやタグを検索出来るようにする

カテゴリーやタグを検索出来るようにする

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句を使用して変更してください。

2020 KumaTechLab.