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フィルターでカスタムフィールドを検索対象に追加すると、サブクエリが増えてパフォーマンスが低下することがあります。投稿数が多いサイトではRelevanssiElasticPressなどの専用プラグインを使ってください
  • pre_get_postsでカスタム投稿タイプを追加する場合、is_main_query()is_search()の両方を確認してください。管理画面の検索も変えてしまわないようis_admin()チェックも必要です
  • Elasticsearchは別途サーバーのセットアップが必要です。小〜中規模サイトはRelevanssi(無料)で十分です

まとめ

検索機能の改善は①wp evalで検索SQLと対象投稿タイプを確認、②pre_get_postsフックでカスタム投稿タイプ(productfaq等)を検索対象に追加、③posts_searchフィルターでwp_postmetaのカスタムフィールド値をサブクエリで検索対象に追加、④posts_orderbyでタイトル一致を優先する並び順を実装、⑤大規模サイトはRelevanssiプラグインで全文インデックス検索に切り替えます。

お気軽にご相談ください

お見積りへ お問い合わせへ