2026年5月20日
2026年5月20日
WordPressの検索機能が正しく動かない問題を解決する方法
はじめに
WordPressのデフォルト検索はタイトルと本文のみを対象とし、カスタムフィールドやカスタム投稿タイプは含まれません。pre_get_postsフックで検索範囲を拡張したり、専用の検索プラグインを導入することで精度を向上させます。
症状・原因
- 検索してもヒットしない・関係ない記事ばかり出てくる
- カスタム投稿タイプが検索結果に含まれない
- カスタムフィールドの内容で検索できない
- 検索結果の並び順が意図通りにならない
解決手順
ステップ1:検索の現状を確認する
# 現在の検索クエリを確認
wp eval "
\$q = new WP_Query([
's' => 'テスト',
'post_type' => 'any',
'posts_per_page' => 5,
]);
echo 'Found: ' . \$q->found_posts . PHP_EOL;
echo 'SQL: ' . \$q->request . PHP_EOL;
"
# 検索対象の投稿タイプを確認
wp eval "
\$types = get_post_types(['exclude_from_search' => false], 'names');
print_r(\$types);
"
ステップ2:カスタム投稿タイプを検索に含める
// functions.php: カスタム投稿タイプを検索結果に含める
// 方法1: register_post_type 時に exclude_from_search = false を設定
register_post_type('product', [
'label' => '商品',
'public' => true,
'exclude_from_search' => false, // ← 検索に含める
'has_archive' => true,
]);
// 方法2: 既存の投稿タイプを pre_get_posts で追加
add_action('pre_get_posts', function(WP_Query $query): void {
if (!$query->is_main_query() || !$query->is_search() || is_admin()) {
return;
}
// 検索対象の投稿タイプを指定
$query->set('post_type', ['post', 'page', 'product', 'faq']);
// ステータスを publish のみに限定
$query->set('post_status', 'publish');
// 1ページあたりの件数
$query->set('posts_per_page', 20);
});
ステップ3:カスタムフィールドを検索対象に追加する
// functions.php: カスタムフィールドの値も検索対象に含める
add_filter('posts_search', function(string $search, WP_Query $query): string {
if (!$query->is_search() || !$query->is_main_query()) {
return $search;
}
global $wpdb;
$search_term = $query->get('s');
if (empty($search_term)) {
return $search;
}
$like = '%' . $wpdb->esc_like($search_term) . '%';
// postmeta からの追加検索クエリ
$meta_search = $wpdb->prepare(
" OR {$wpdb->posts}.ID IN (
SELECT post_id FROM {$wpdb->postmeta}
WHERE meta_key IN ('product_description', 'faq_answer')
AND meta_value LIKE %s
)",
$like
);
return $search . $meta_search;
}, 10, 2);
ステップ4:検索結果の並び順と精度を改善する
// functions.php: 検索結果をタイトル一致を優先して並び替え
add_filter('posts_orderby', function(string $orderby, WP_Query $query): string {
if (!$query->is_search() || !$query->is_main_query()) {
return $orderby;
}
global $wpdb;
$search_term = $wpdb->esc_like($query->get('s'));
// タイトルに検索語が含まれる場合を優先
return "CASE WHEN {$wpdb->posts}.post_title LIKE '%{$search_term}%'
THEN 0 ELSE 1 END ASC,
{$wpdb->posts}.post_date DESC";
}, 10, 2);
// 検索結果から特定のカテゴリを除外
add_action('pre_get_posts', function(WP_Query $query): void {
if (!$query->is_search() || !$query->is_main_query() || is_admin()) {
return;
}
// カテゴリID 5, 10 を除外
$query->set('category__not_in', [5, 10]);
});
ステップ5:全文検索プラグインを導入する
# SearchWP(高精度な検索プラグイン)をインストール
# または Relevanssi(無料・高機能)
wp plugin install relevanssi --activate
# Relevanssi のインデックスを構築
wp eval "
if (function_exists('relevanssi_build_index')) {
relevanssi_build_index();
echo 'Index built successfully';
}
"
# ElasticPress(Elasticsearch連携・大規模サイト向け)
wp plugin install elasticpress --activate
// Relevanssi の検索対象をカスタマイズ
add_filter('relevanssi_index_custom_fields', function(array $fields): array {
$fields[] = 'product_description';
$fields[] = 'faq_answer';
$fields[] = '_yoast_wpseo_metadesc'; // Yoast SEO のメタ説明
return $fields;
});
// Relevanssi で検索時のスコアリングをカスタマイズ
add_filter('relevanssi_match', function(object $match): object {
// タイトル一致のスコアを3倍に
$match->title_relevance *= 3;
return $match;
});
注意事項
posts_searchフィルターでカスタムフィールドを検索対象に追加すると、サブクエリが増えてパフォーマンスが低下することがあります。投稿数が多いサイトではRelevanssiやElasticPressなどの専用プラグインを使ってくださいpre_get_postsでカスタム投稿タイプを追加する場合、is_main_query()とis_search()の両方を確認してください。管理画面の検索も変えてしまわないようis_admin()チェックも必要です- Elasticsearchは別途サーバーのセットアップが必要です。小〜中規模サイトはRelevanssi(無料)で十分です
まとめ
検索機能の改善は①wp evalで検索SQLと対象投稿タイプを確認、②pre_get_postsフックでカスタム投稿タイプ(product・faq等)を検索対象に追加、③posts_searchフィルターでwp_postmetaのカスタムフィールド値をサブクエリで検索対象に追加、④posts_orderbyでタイトル一致を優先する並び順を実装、⑤大規模サイトはRelevanssiプラグインで全文インデックス検索に切り替えます。