Elasticsearch × Drupalで理解する日本語サイト内検索
この記事では、Elasticsearch × Drupalで日本語サイト内検索を実装する方法を解説します。
サイト内のコンテンツを検索するという行為は、コンテンツが増えれば増えるほどニーズは高まり、重要になっていきます。スケーリングに優れたオープンソースの全文検索エンジン「Elasticsearch」と、大規模サイトでの利用が多いオープンソースCMS「Drupal」で、大量コンテンツを日本語で検索可能にする優れたサイト内検索を実装できます。連携モジュールが用意されており、数クリックで導入できるのもポイントです。
過去にウェビナーでも取り上げた内容です。同内容を動画でもご覧いただけます。
Drupalのサイト内検索について
Drupalでサイト内検索を実現する方法は、主に2つあるのではないかと思います。
方法1つ目は、Drupalの標準機能で用意されている検索機能を利用する方法です。
具体的には、Drupalコアで提供されるSearchモジュールを用いることになります。標準機能に含まれており、設定もシンプルなので、すぐに使い始められるのが特徴です。日本語検索については「簡易CJK処理」(N文字数で単語を区切る、いわゆるN-gramと呼ばれる分割方法)で対応が可能です。
インデックスがデータベースに保存されるので、コンテンツが大量に存在する大規模サイトだとパフォーマンスに気をつけなければいけません。また、検索の処理に関しては、形態素解析や辞書を用いて日本語検索の細かいチューニングを行いたい、というニーズは叶えられません。
方法2つ目は、Search APIモジュールとその周辺モジュールで検索機能を提供する方法です。
Search APIモジュールとは、よく利用されている人気のコントリビュートモジュールの1つで、Drupalで検索機能を提供するためのフレームワークとして機能します。
Search APIを利用することで、検索サーバーはデータベース、Apache Solr、Elasticsearchなどを利用することができ(もちろん検索サーバーは別途調達する必要があります)、検索サーバーをDrupalデータベースから切り離してあげることで大規模サイトにも対応可能です。検索画面はViews機能とシームレスに統合しているのできめ細やかなカスタマイズが行えます。
Search APIをカスタマイズするためのフックやプラグインが豊富に用意されているため、バックエンド、フロント共に用途に合わせたカスタマイズも柔軟に行うことができます。そのことから、Search APIを中心に便利な関連モジュールが多数公開されており、Search APIという共通したフレームワーク上で大きなエコシステムが発達しています。日本語検索はバックエンドの検索エンジンによって細かく設定することが可能です。
Search APIの検索エンジンにElasticsearchを使用する
今回の本題である、ElasticsearchとDrupalの連携はまさにSearch APIモジュールを介して行われます。Search APIのバックエンドの検索エンジンをElasticsearchに繋げるためには、Elasticsearch Connectorモジュールが追加で必要です。このモジュールはElasticsearchの最新バージョン(執筆時点で7系)まで対応しています。
DrupalサイトにElasticsearchを導入してみよう
ここからは実際に、これらのモジュールを使用して、Drupalのサイト内検索をElasticsearchで実現するための設定方法をご紹介します。
手順
1. Elasticsearch ConnectorとSearch APIモジュールの導入
必要な二つのモジュールをComposerでインストールします。Drupalのプロジェクトディレクトリ直下で、次のコマンドを実行します。
$ composer require drupal/search_api drupal/elasticsearch_connector
$ composer require drupal/elasticsearch_connector
二つのモジュールを有効化します。Drupalの管理画面から、もしくは次のコマンドを実行します。
$ drush pm:enable search_api elasticsearch_connector
これで二つのモジュールがDrupalサイトで利用できるようになりました。
2. DrupalをElasticsearchに接続する
管理メニューから 環境設定 > 検索とメタデータ > Elasticsearch Connector をクリックして、設定画面を開きます。[+Add cluster] をクリックして、接続するElasticsearchを登録します。
Elasticsearchサーバーへの接続が成功すると、Cluster Statusに yellow や green と表示されます。
3. インデックスの設定と作成
まず前提として、Drupal内でいくつかコンテンツが用意されている状態で行います。
Search APIモジュールによって、Elasticsearch、Apache Solrなどのさまざまな検索サーバーにプッシュするための抽象化レイヤが提供されており、Search APIを通じて操作できるようになっています。
Search API側でElasticsearchサーバーを管理するための設定を行います。管理メニューから 環境設定 > 検索とメタデータ > Search API の設定画面を開きます。
[+ Add server] をクリックして、先ほどElasticsearch Connectorで登録したサーバーを選択して保存します。
サーバーを作成したら、次はインデックスを作成します。[+Add index] をクリックします。Datasourcesに [コンテンツ] を指定しましょう。
Index Options の、[Index items immediately] にチェックを入れた状態で保存をすると、保存したタイミングでDrupalのコンテンツがElasticsearchサーバーにインデックスされます。
ブラウザで次のURLを開いて、Elasticsearchサーバーでのインデックスの作成を確認すると、インデックスが一つ作成されていることがわかります。
https://{elasticsearchサーバー}/_cat/indices?v
次はインデックスに登録されたドキュメントを見てみます。次のURLにアクセスすると、確かにDrupalのコンテンツがElasticsearchのドキュメントとして保存されていますが、タイトルや本文など、Drupalのコンテンツが持つフィールドは見当たりません。
https://{elasticsearchサーバー}/{インデックス名}/_search
これは、Search APIのインデックスの設定で、フィールドが追加されていないためです。
フィールドタブでは、Drupalデータが持つフィールドから、Elasticsearchサーバーに送信するものを選択できます。デフォルトでは何も選択されていない状態なので、[+ Add fields] からフィールドを追加します。
Elasticsearch側で既に作成されたドキュメントにフィールド情報を反映させるには、[Rebuild tracking information] > [Index now] を順にクリックします。
Elasticsearch側を確認すると、ドキュメントにフィールド情報が付与されたことがわかります。
※ フィールドの定義はElasticsearchで言うところのmappingに相当します。Elasticsearchの仕様上、一度追加したフィールドに対してデータタイプやブーストなど設定の変更は出来ません。変更を行う場合はインデックスの再作成(re-Index)をする必要があります。
他にもプロセッサータブでは、Drupalデータを検索サーバーにインデックスする前や、検索クエリを投げる前に何らかの処理をさせることが出来ます。例えばインデックスの前処理として「公開済み」コンテンツのみをインデックスさせる「Entity status」プロセッサーなどがあります。
4. Views機能で検索結果ページの作成
エンドユーザーに提供するワード検索ボックスや検索結果のページは、Drupalの「Views」機能で作成します。
管理画面のメニューから「Views」画面に移動して、Viewを1つ作成します。
ビューの設定項目で、Search APIで設定したインデックスを指定することで、Elaticsearchサーバーに対して検索クエリを投げることができます。
あとは通常のViewを作成する時と同様に設定を行うだけです。
日本語検索を良くするには?
さて、ここまで紹介した方法では、日本語検索における設定は何も行なっておりません。Elasticsearchのデフォルトの設定で日本語の全文検索を行うとノイズが発生してしまうため、日本語の形態素解析エンジンである「kuromoji」プラグインを導入することが一般的です。kuromojiの導入方法、設定方法は「でぶちゃんねる vol28」動画内で解説がありますのでぜひご覧ください。
参考資料