カスタムフィールドの値も検索対象に含めたい

WordPress

以前は、「Search Everything」というプラグインを使用しておりました。
ですがこちらのプラグイン、検索が非常に重くなるのと、別プラグインとの組み合わせで不具合が発生したりしていました。

今回は、プラグインを使用しない方法をご紹介致します。

スポンサーリンク

実装コード

functions.php に以下コードをまるコピーするだけ!!

<?php
function cf_search_join($join) {
	global $wpdb;
	if (is_page('search')) {
		$join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
	}
	return $join;
}
add_filter('posts_join', 'cf_search_join');

function cf_search_where($where) {
	global $wpdb;
	if (is_page('search')) {
		$where = preg_replace(
			"/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
			"(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where);

		// 特定のカスタムフィールドを検索対象から外す
		// $where .= " AND (" . $wpdb->postmeta . ".meta_key NOT LIKE 'sample')";
	}
	return $where;
}
add_filter('posts_where', 'cf_search_where');

function cf_search_distinct($where) {
	global $wpdb;
	if (is_page('search')) {
		return "DISTINCT";
	}
	return $where;
}
add_filter('posts_distinct', 'cf_search_distinct');

参考サイト

https://adambalee.com/search-wordpress-by-custom-fields-without-a-plugin/

意図した結果が得られない時

このままでも検索自体はできるのですが、キーワードによっては、意図しない記事が出てきてしまうこともあります。
それは通常のLIKE検索では、濁点・半濁点、ひらがな・カタカナを区別しないためになります。

例えば、ぱん で検索すると

  • アンパン
  • ばんそうこ
  • はんこ
  • ハンペン

なども全てヒット対象になっていまします。

濁点・半濁点、ひらがな・カタカナを厳密にするには、BINARY演算子を使用します。
各 LIKE 検索のところに BINARY を追加してください。

<?php
function cf_search_join($join) {
	global $wpdb;
	if (is_page('search')) {
		$join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
	}
	return $join;
}
add_filter('posts_join', 'cf_search_join');

function cf_search_where($where) {
	global $wpdb;
	if (is_page('search')) {
		$where = preg_replace(
			"/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
			"(".$wpdb->posts.".post_title LIKE BINARY $1) OR (".$wpdb->postmeta.".meta_value LIKE BINARY $1)", $where);

		// 特定のカスタムフィールドを検索対象から外す
		// $where .= " AND (" . $wpdb->postmeta . ".meta_key NOT LIKE BINARY 'sample')";
	}
	return $where;
}
add_filter('posts_where', 'cf_search_where');

function cf_search_distinct($where) {
	global $wpdb;
	if (is_page('search')) {
		return "DISTINCT";
	}
	return $where;
}
add_filter('posts_distinct', 'cf_search_distinct');

余談ですが、検索方式を「LIKE」から「LIKE BINARY」へ変更したい場合も同様になります。

function my_posts_where( $where, $obj ) {
	if ( $obj->is_search ) {
		$where = str_replace( 'LIKE', 'LIKE BINARY', $where );
	}
	return $where;
}
 add_filter( 'posts_where', 'my_posts_where', 10, 2 );

コメント

スポンサーリンク
タイトルとURLをコピーしました