2026年8月18日

2026年8月18日

WordPressの検索をElasticsearchにする方法(ElasticPress・日本語のkuromoji設定)

WordPress の標準のサイト内検索は、データベース(MySQL・MariaDB)で投稿のタイトル・抜粋・本文に検索語が含まれるかを LIKE で調べる仕組みです。投稿が多いと遅くなりやすく、並び順も「関連の強さ」ではありません。プラグイン ElasticPress を使うと、検索を全文検索エンジンの Elasticsearch に任せられます。

この記事の手順は、2026年11月時点の WordPress 7.1、ElasticPress 5.3.5、Elasticsearch 9.5.5(Docker)で動作を確かめています。

構成と必要なもの

  • Elasticsearch のサーバー: 自分で用意する(VPS や Docker)か、ElasticPress の開発元が提供するホスティングサービス ElasticPress.io を使います。共用のレンタルサーバーでは Elasticsearch を動かせないことがほとんどです。
  • ElasticPress プラグイン: WordPress の検索クエリ(WP_Query)を Elasticsearch への問い合わせに置き換えます。公式の要件は WordPress 6.2 以上、PHP 7.4 以上、Elasticsearch 5.2 以上です。

ElasticPress を入れると、投稿の内容が Elasticsearch のインデックスにコピーされ、検索のときはそちらが使われます。投稿を保存・削除したときは、ElasticPress が自動でインデックスを更新します。

Elasticsearchを起動する(Docker・日本語プラグイン入り)

日本語の文章を単語に分けるには、Elasticsearch の公式プラグイン analysis-kuromoji(形態素解析)が必要です。コンテナを作り直しても消えないよう、プラグインを入れたイメージを作ります。作業用のディレクトリに次の2つのファイルを置きます。

Dockerfile:

FROM elasticsearch:9.5.5
RUN bin/elasticsearch-plugin install --batch analysis-kuromoji

compose.yaml:

services:
  elasticsearch:
    build: .
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - ES_JAVA_OPTS=-Xms512m -Xmx512m
    ports:
      - "127.0.0.1:9200:9200"
    volumes:
      - es-data:/usr/share/elasticsearch/data

volumes:
  es-data:
docker compose up -d --build

# 起動の確認("status" が green か yellow なら動いている)
curl -s "http://127.0.0.1:9200/_cluster/health?pretty"

# kuromoji が入っているかの確認
curl -s "http://127.0.0.1:9200/_cat/plugins"

この設定は、同じサーバーの WordPress から使う開発・検証用です。

  • xpack.security.enabled=false で認証と暗号化を切っているため、ports は 127.0.0.1 に限定し、外部から接続できないようにしています。インターネットに公開する構成では使わないでください。
  • 本番では、Elasticsearch の公式文書に沿って認証と HTTPS を有効にし、メモリ(ES_JAVA_OPTS のヒープの大きさ)やカーネルの設定(vm.max_map_count)を見直します。

Elasticsearch のインストール全般は Elasticsearchのインストール方法 を参照してください。

ElasticPressを入れて同期する

1. プラグインを入れる

「プラグイン」→「プラグインを追加」で「ElasticPress」を検索し、インストールして有効化します。

2. 接続先を設定する

接続先を wp-config.php に書きます(管理画面の ElasticPress の設定画面で入力することもできます)。

<?php
// wp-config.php(「That's all, stop editing!」の行より前)
define( 'EP_HOST', 'http://127.0.0.1:9200/' );

// Elasticsearch の認証を有効にしている場合は、ユーザー名とパスワードを指定する
// define( 'ES_SHIELD', 'ユーザー名:パスワード' );

3. 投稿を同期する

投稿を Elasticsearch に送ります(同期)。管理画面の「ElasticPress」→「Sync」からも実行できますが、投稿が多いサイトでは WP-CLI が確実です。

wp elasticpress status                 # 接続の確認
wp elasticpress sync --setup --yes     # インデックスを作り直して全件を送る
wp elasticpress list-features          # 有効な機能(search が含まれていること)

試した環境では Number of posts indexed: 30 と表示され、公開中の投稿と固定ページが送られました。ElasticPress の「検索」機能(search)は有効化した時点で有効になり、フロントのサイト内検索(?s=)が Elasticsearch で処理されます。

--setup はインデックスを削除して作り直す指定です。後で説明する日本語の設定のように、インデックスの設定(マッピング)を変えたときは、--setup 付きで同期し直します。同期の直後は反映に少し時間がかかり、試したところ同期と同じ処理の中ですぐ検索すると結果が0件でした。

日本語を単語に分ける(kuromoji)

ElasticPress は、サイトの言語に合わせて Elasticsearch の言語設定を選びますが、2026年11月時点の ElasticPress 5.3.5 には日本語の対応表がなく、日本語のサイトでも英語用の設定(標準のトークナイザー)が使われます。標準のトークナイザーは漢字を1文字ずつに分けるため、たとえば「京都」で検索すると「東京都」を含む投稿も見つかります。

次のファイルを wp-content/mu-plugins/ep-japanese.php として置くと、投稿のインデックスで kuromoji を使うようになります。

<?php
/**
 * Plugin Name: ElasticPress Japanese analyzer
 * Description: ElasticPress の投稿インデックスで kuromoji(日本語の形態素解析)を使う。
 */

// 投稿インデックスの既定のアナライザーを kuromoji に置き換える
add_filter( 'ep_post_mapping', function ( $mapping ) {
	$analyzer = array(
		'type'        => 'custom',
		'char_filter' => array( 'html_strip' ),
		'tokenizer'   => 'kuromoji_tokenizer',
		'filter'      => array(
			'kuromoji_baseform',
			'kuromoji_part_of_speech',
			'cjk_width',
			'ja_stop',
			'kuromoji_stemmer',
			'lowercase',
		),
	);
	$mapping['settings']['analysis']['analyzer']['default']        = $analyzer;
	$mapping['settings']['analysis']['analyzer']['default_search'] = $analyzer;
	return $mapping;
} );

置いた後に wp elasticpress sync --setup --yes で同期し直します。設定が入ったかは、インデックス名を調べてから、その設定を表示して確かめます(default のアナライザーに kuromoji_tokenizer が出ていれば反映されています)。

wp elasticpress get-indices
# 表示されたインデックス名(例: example-com-post-1)を指定する
wp elasticpress get-index-settings example-com-post-1 --pretty

試した結果は次のとおりです(5件の日本語の投稿で比較)。

検索語 標準のトークナイザー kuromoji
京都 「京都の観光情報」と「東京都」を含む投稿の2件 「京都の観光情報」の1件
速い 「高速化」を含む投稿の1件 「速くなります」を含む投稿も見つかり2件

kuromoji は「速く」を基本形の「速い」として扱うため、活用した形でも見つかります。一方で、単語の途中の文字列(例:「東京都」の中の「京都」)では見つからなくなります。どちらが合うかはサイトの内容によるので、実際の投稿で試して決めてください。

特定の投稿を検索から外す

ElasticPress は、初期設定では公開中(publish)の投稿だけを送ります。下書きや非公開の投稿を除くための設定は不要です。それ以外に、たとえばカスタムフィールドで指定した投稿を外したい場合は、全件の同期と、投稿の保存時の同期の両方で除外します。

<?php
// 全件の同期(wp elasticpress sync)で、_myprefix_exclude_search が 1 の投稿を除く
add_filter( 'ep_post_query_db_args', function ( $args ) {
	$args['meta_query'] = array(
		'relation' => 'OR',
		array(
			'key'     => '_myprefix_exclude_search',
			'compare' => 'NOT EXISTS',
		),
		array(
			'key'     => '_myprefix_exclude_search',
			'value'   => '1',
			'compare' => '!=',
		),
	);
	return $args;
} );

// 投稿の保存時の同期でも、同じ投稿を送らない
add_filter( 'ep_post_sync_kill', function ( $skip, $post_id ) {
	if ( '1' === get_post_meta( $post_id, '_myprefix_exclude_search', true ) ) {
		return true;
	}
	return $skip;
}, 10, 2 );

試したところ、このフィールドを付けた投稿は同期の対象から外れ、本文に検索語を含んでいても検索結果に出ませんでした。なお ep_post_sync_kill は「送らない」だけなので、すでにインデックスに入っている投稿にあとからフィールドを付けた場合は、wp elasticpress sync --setup --yes で同期し直します。

絞り込みと重み付けは管理画面で設定する

ElasticPress には、検索結果の絞り込みや並び順の調整が機能として入っています。独自のクエリを書く前に、まずこれらを使います。

  • 絞り込み(Filters 機能): 初期状態で有効で、「Filter by Taxonomy」「Filter by Post Type」「Filter by Metadata」「Filter by Post Date」などのブロックが使えます。検索結果やアーカイブのテンプレートに置くと、カテゴリーやタグなどで結果を絞り込めます。
  • 重み付け: 「ElasticPress」→「Search Fields & Weighting」で、タイトル・本文・抜粋・タクソノミーなどのどれを検索対象にし、どれを重く見るかを設定できます。「Add field」でカスタムフィールド(Metadata key)を検索対象に加えることもできます。

うまく動かないとき

  • wp elasticpress status がエラーになる: EP_HOST の URL(http/https、ポート、末尾の /)と、WordPress のサーバーから Elasticsearch に接続できるか(curl で /_cluster/health が返るか)を確かめます。
  • 検索結果が変わらない: wp elasticpress list-features に search があるか、同期が終わっているかを確かめます。
  • 日本語の設定が効かない: ep-japanese.php を置いた後に --setup 付きで同期し直したか、Elasticsearch に analysis-kuromoji が入っているか(/_cat/plugins)を確かめます。

関連記事

お気軽にご相談ください

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