前回までに,Solr/Luceneの概要と簡単な導入検証までを説明しました。Lucene自体はライブラリであることから,これを利用して高度なアプリケーションを独自に実装することも可能ですが、簡単な検索機能であればSolrを利用し、比較的容易に利用できることがお分かりいただけたのではないでしょうか。今回は,導入のための留意点と,周辺のツール類を紹介します。

Solr/Lucene導入の実際

 では,導入時の留意点について順に説明してきましょう。

●インデックス設計

 一般的に全文検索エンジンは,プレーンテキストのような非構造化データを効率良く検索するものです。そのため,データを格納するインデックスに対して,データを「ともかく放り込む」といった設計も可能です。

 誤解を恐れずにいえば,その考え方自体は大きく間違っていません。しかし,インデックスの構造を充分に設計した方が,より効率の良い効果的な検索機能を実現できます。

 SolrではXML形式のファイルでインデックスの構造(スキーマ)を定義します。例えば,ECサイトで検索エンジンを導入する場合では“商品カテゴリで絞り込みながら商品説明本文を全文検索したい”というようなニーズがあります。この場合に「絞り込み用の商品カテゴリフィールド」と「全文検索用の商品説明フィールド」を個別に定義することで,商品カテゴリは完全一致,商品説明は形態素解析で全文検索といった使い分けが可能になります。

●データ鮮度/インデキシング時間

 インデックスを使う全文検索エンジンは,その構成上必ず「データをインデックスに格納する処理の時間=インデキシング時間」が必要です。Solrの場合,前回のサンプルでは7つのフィールドから構成される約15万7000件程度のデータを10のフィールドを持つインデックスに展開・格納しましたが,筆者の環境(Intel Core2 Duo 1.8GHz/512MB RAM/CentOS 5.3 x86_64)では5分程度で処理を完了しました。

 これを速いと見るか遅いと見るかは適用対象システムの要件次第です。単純なインデキシング処理で必要なデータ鮮度を確保できない場合,インデキシング方法の工夫が必要になります。その際には「分散して複数のインデックスを作成し最後にマージする」などの作り込みを実施することで,インデキシング処理の総時間を短縮可能です。

 具体的な対処方式は,要件ごとに最適なものを選択することになりますが,いずれにしても「インデキシング時間の見積」や「追加開発が発生する場合の工数見積」など,要件検討段階で充分に留意する必要があります。

●言語解析処理の特性に関する配慮

 第4回で説明した通り,日本語全文検索には言語解析処理が不可欠になります。現在主流の方式としてN-Gramと形態素解析を挙げましたが,これらの方式はそれぞれ異なる特性を持っています。

 一般に検索結果の品質を表す評価軸として「再現率」と「適合率」の2つがあります。それぞれ「条件に一致する文が漏れなくヒットする率」と「条件に一致しない結果(ノイズ)がどれだけ含まれないか」を示す指標であり,この2つの評価はトレードオフの関係になります。

 つまり,確実にヒットする場合にはノイズも増え,ノイズを減らそうとするとヒットしないデータが増加する,というものです。この評価軸では通常,「N-Gram=再現率>適合率」となり,「形態素解析=再現率<適合率」になります。

 ただし形態素解析の適合率は辞書の内容/精度に依存し,辞書に無い専門用語が多量に含まれたデータでは,必ずしも期待通りに適合率が向上しない可能性もあります。このような場合に,辞書の内容を充実させることで適合率の向上が見込めますが,言語解析処理の採用にあたっては上述のような特性に配慮する必要があります。

●検索結果のチューニング

 全文検索エンジンによる検索では複数のデータがヒットする可能性があります。それらの検索結果は,全文検索エンジンが持つ“スコアリング・ロジック”に従って順位が決定され,基本的に「より一致度の高いデータ」を上位に表示します。

 Solr/Luceneも内部にスコアリング機能を持っています。特にパラメータを指定しない限り,デフォルトのスコアリングで検索結果が決定されますが,要件によっては検索結果の順位等を恣意的に制御したいケースもあるでしょう。

 Solr/Luceneでは特定フィールドによるソート,フィールド毎の重み付け(フィールドAの一致度をフィールドBの一致度より優先するなど)機能などを利用可能なので,要件を検討する場合はこれらのチューニング要素を加味できます。

●スケーラビリティ/可用性

 全文検索エンジンは本質的にほとんど読み込み処理となります。そのため,前面でリクエストを受け付けるSolr自体は,比較的単純にスケールアウトさせることができます。

 単純なスケールアウトではノードごとにインデックスを作成する構成になりますが,検索処理の性能はインデックスへの入出力処理に強く依存します。そのためインデックスのサイズが一定のボリュームを超えると個々のSolrの性能が低下してしまい,スケールアウトのメリットが充分に生かせなくなる可能性があります。

 Solrは1.3から「Distributed Search」という機能を備えています。これは,パーティショニングしたインデックス(単一のデータセットをノードごとに分割したインデックス)を持つSolrを複数ノードに配置し,それらのSolrを透過的/横断的に検索する機能です。この機能を用いると,全体として巨大なインデックスを複数ノードに分散して検索できるようになります。

 Distributed Searchで構成したSolrの場合,各ノードが保持するインデックスの内容が異なることから,実態的には「複数ノードから構成されたシングルポイント」となります。そのため,複数のノード配置による可用性の向上は期待できませんが,前述「入出力性能にひきずられて性能が向上しない」というようなケースでは有効な対策となります。ちなみに,Solr1.3が仕様上サポートするインデックスのレコード数上限値は(あくまで「仕様上」ですが)900京件を越えます。