WordPressで「あいまい検索」を実装して近い条件の記事を表示させる方法|検索結果0件を防ぐ設定とカスタマイズ

WordPressサイト内検索で、例えば「伝言メモ テンプレート」と2つのキーワードを入力した際、該当記事が0件になってしまった経験はないでしょうか。
サイト内には「テンプレート集」や「電話メモ・伝言のルール」といった関連情報が存在しているにもかかわらず、標準のWordPress検索では1文字でもキーワードの組み合わせが完全一致しないと「記事が見つかりませんでした」と判定されてしまいます。
本記事では、Google検索のように「完全一致が見つからない場合は、キーワードに近い結果を表示する」仕組みを、テーマファイルを一切触らずにCode Snippetsだけで実装する方法を含め徹底解説します。

WordPress標準検索で「近い条件の記事」が表示されない理由

WordPressのデフォルト検索機能(/?s=キーワード)は、非常にシンプルかつ厳格な仕様になっています。
複数キーワードをスペース区切りで入力した場合、内部のデータベース処理では「すべてのキーワードを完全に含む記事のみを抽出する(AND検索)」が行われます。

WordPress標準検索で該当記事が0件になる画面キャプチャ

標準検索で「伝言メモ テンプレート」を検索したときの0件画面(関連情報があってもヒットしない)

標準検索には、主に以下のような課題や制約があります。

WordPress標準検索の主な制約:

  • 厳格なAND完全一致: 「伝言メモ」と「テンプレート」の2語を入力した場合、両方の文字列が同時に含まれる記事しかヒットしません。片方しか含まれない記事はすべて除外されます。
  • 部分一致・表記揺れの非対応: 「テンプレ」「フォーマット」「電話メモ」といった同義語や表記揺れを自動で認識できません。
  • 形態素解析(単語分割)の不在: 日本語の文脈に応じた品詞分解を行わず、SQLの LIKE '%キーワード%' による単純な文字列マッチングを行うため、語句の区切りを柔軟に扱えません。
  • スコアリング・関連度ソートの弱さ: 記事タイトルや見出しにキーワードが含まれているかどうかの重み付けが限定的で、関連順ではなく単なる公開日順で並びやすい傾向があります。

この結果、ユーザーは「このサイトには目的の情報がない」と判断して即座に離脱してしまいます。
これを防ぐためには、Google検索のように「一致する情報が見つからない場合は、キーワードに近い結果を表示する」仕組みが必要です。

WordPress標準検索とあいまい検索のアルゴリズム比較図解

標準検索(AND完全一致)とあいまい検索(OR+関連度スコアリング)の違い

あいまい検索・近い条件の記事を表示させるアプローチ

WordPressサイトにあいまい検索や近い記事の表示機能を組み込むには、主に以下の方法があります。

実現アプローチの一覧:

  • Google検索風スニペット(おすすめ): テーマを触らずCode Snippetsだけで「0件時にキーワードに近い結果」を案内枠付きで表示
  • プラグイン導入: RelevanssiやSearchWP等の専用検索プラグインを活用
  • functions.phpカスタマイズ: 検索クエリを常時OR検索に変更
  • AIセマンティック検索: ベクトル検索(Embedding)を活用した意味・文脈による類似記事抽出

テーマ編集不要!Google検索風「キーワードに近い結果」スニペット

Google検索では、完全一致するページがない場合、「『〇〇』と一致する情報は見つかりませんでした。次の検索結果を表示しています: キーワードに近い結果」という案内が表示され、探していた単語の一部を含む関連ページが自動的に提示されます。

このGoogle検索のような挙動を、テーマファイル(search.phpなど)を一切編集せず、「Code Snippets」プラグイン(または functions.php)に貼るだけで実装できるPHPスニペットが以下です。

/**
 * 検索結果0件時にGoogle検索風「キーワードに近い結果」を表示するスニペット
 * (Code Snippets / functions.php 用・テーマ編集不要)
 */

// 1. 完全一致が0件だった場合に、キーワードを分解して近い記事を差し込む
add_filter( 'the_posts', 'google_style_fuzzy_search_fallback', 10, 2 );
function google_style_fuzzy_search_fallback( $posts, $query ) {
    if ( ! is_admin() && $query->is_main_query() && $query->is_search() && empty( $posts ) ) {
        $search_query = $query->get( 's' );
        // スペースやカンマでキーワードを分割
        $keywords = preg_split( '/[\s,]+/', $search_query, -1, PREG_SPLIT_NO_EMPTY );

        if ( ! empty( $keywords ) ) {
            global $wpdb;
            
            // 各キーワードに対するOR条件を生成
            $where_clauses = array();
            foreach ( $keywords as $word ) {
                $escaped = '%' . $wpdb->esc_like( $word ) . '%';
                $where_clauses[] = $wpdb->prepare(
                    "({$wpdb->posts}.post_title LIKE %s OR {$wpdb->posts}.post_content LIKE %s)",
                    $escaped,
                    $escaped
                );
            }

            $sql = "
                SELECT DISTINCT {$wpdb->posts}.*
                FROM {$wpdb->posts}
                WHERE {$wpdb->posts}.post_type = 'post'
                  AND {$wpdb->posts}.post_status = 'publish'
                  AND (" . implode( ' OR ', $where_clauses ) . ")
                ORDER BY {$wpdb->posts}.post_date DESC
                LIMIT 10
            ";

            $fallback_posts = $wpdb->get_results( $sql );

            if ( ! empty( $fallback_posts ) ) {
                // Google風メッセージ表示用フラグとデータを保持
                $GLOBALS['is_google_fuzzy_fallback'] = true;
                $GLOBALS['google_fuzzy_original_query'] = $search_query;
                $GLOBALS['google_fuzzy_keywords'] = $keywords;

                // 検索結果件数を補正
                $query->post_count = count( $fallback_posts );
                $query->found_posts = count( $fallback_posts );
                $query->max_num_pages = 1;

                return $fallback_posts;
            }
        }
    }
    return $posts;
}

// 2. 検索結果一覧の上部にGoogle検索風のインフォメーション枠を自動表示
add_action( 'loop_start', 'display_google_style_search_notice' );
function display_google_style_search_notice( $query ) {
    if ( ! empty( $GLOBALS['is_google_fuzzy_fallback'] ) && $query->is_main_query() ) {
        static $displayed = false;
        if ( $displayed ) return;
        $displayed = true;

        $original_query = esc_html( $GLOBALS['google_fuzzy_original_query'] );
        $keywords = $GLOBALS['google_fuzzy_keywords'];

        // 各単語への再検索リンクチップを生成
        $chips_html = '';
        foreach ( $keywords as $kw ) {
            $kw_escaped = esc_html( $kw );
            $kw_url = esc_url( home_url( '/?s=' . urlencode( $kw ) ) );
            $chips_html .= '' . $kw_escaped . '';
        }

        echo '
        

' . $original_query . '」と完全に一致する記事は見つかりませんでした。

次の検索結果を表示しています: キーワードに近い結果

単語ごとに検索: ' . $chips_html . '
'; } }
あいまい検索改善後のWordPress検索結果画面キャプチャ

Google検索風の案内枠と近い結果の表示イメージ

プラグインを活用したあいまい検索の実装

管理画面からさらに高度な重み付けや同義語設定を行いたい場合は、実績のある検索プラグインを活用します。

WordPress検索設定プラグインの管理画面キャプチャ

プラグイン管理画面でのOR検索・ファジー検索(部分一致)・重み付け設定例

おすすめの検索プラグイン

Relevanssi(レレバンシ)

WordPressで最も定番の無料検索プラグインです。検索結果を関連度順(スコア順)に並べ替え、デフォルトの検索ロジックを「OR検索」に設定できます。
部分一致(Fuzzy Matching)や同義語登録、「もしかして(Did you mean?)」機能も備えています。

SearchWP

カスタムフィールド、PDF文書内テキスト、タグ、タクソノミーまで完全にインデックス化できる高機能プラグインです。

まとめ

WordPressサイトのサイト内検索において、「完全一致がなければ0件」という状態はユーザーの離脱に直結します。

本記事のまとめ:

  • 標準のWordPress検索はAND完全一致のため、複数キーワードで0件になりやすい
  • Google検索のように「〇〇と一致する情報は見つかりませんでした。次の検索結果を表示しています: キーワードに近い結果」と案内することで親切な導線ができる
  • Code Snippetsプラグインを使うことで、テーマファイルを触らずに安全に導入可能

ぜひスニペットを導入して、快適な検索体験を提供してみてください。