関口宏司のLuceneブログ

OSS検索ライブラリのLuceneおよびそのサブプロジェクト(Solr/Tika/Mahoutなど)について
スポンサーサイト

一定期間更新がないため広告を表示しています

| スポンサードリンク | - | | - | - |
小ネタ:QueryParserのユニコードエスケープのサポート
検索式のパーサであるQueryParserクラスは、"¥uXXXX"形式のユニコードエスケープを受け付ける。

プログラム例:



QueryParser qp = new QueryParser( "f", new WhitespaceAnalyzer() );
Query q = qp.parse( "¥u30ED¥u30F3¥u30A6¥u30A4¥u30C3¥u30C8" );
System.out.println( q.toString() );



実行結果:



f:ロンウイット



| 関口宏司 | Luceneクラス解説 | 10:15 | comments(0) | trackbacks(1) |
小ネタ:TermsFilter
商品検索で、色(フィールド名"color")が赤でサイズ(フィールド名"size")が10の商品だけの中から、適当な検索語で検索するようなとき、色やサイズの条件をあらかじめFilterで用意しておけば、すばやく絞り込み検索ができる。

具体的なプログラムコードは次のようになる:



final String F_COLOR = "color";
final String F_SIZE = "size";
Term color = new Term( F_COLOR, "赤" );
Term size = new Term( F_SIZE, "10" );
BooleanQuery bq = new BooleanQuery();
bq.add( new TermQuery( color ), Occur.MUST );
bq.add( new TermQuery( size ), Occur.MUST );
Filter filter = new CachingWrapperFilter( new QueryWrapperFilter( bq ) );



上記はLucene 2.2以降の例である。Lucene 2.1以前では最後の一行を次のように書く:



Filter filter = new QueryFilter( bq );



なぜか、Lucene 2.1以前の方が簡単なのだ。この辺の経緯はこちらに詳しく書いてある

ところで、contribのTermsFilterを使うと、同じことが次のように書いても可能である:



final String F_COLOR = "color";
final String F_SIZE = "size";
Term color = new Term( F_COLOR, "赤" );
Term size = new Term( F_SIZE, "10" );
TermsFilter tf = new TermsFilter();
tf.addTerm( color );
tf.addTerm( size );
Filter filter = new CachingWrapperFilter( tf );



以上のFilterの処理効率はどれも同じなので、使用バージョンと好みによって使い分ければよいだろう。
| 関口宏司 | Luceneクラス解説 | 11:33 | comments(0) | trackbacks(1) |
Luceneインデックスのバージョンの活用
LuceneのインデックスがWebアプリケーションサーバのプログラムから検索できるようになっている環境を考える。そして、クライアント(Webブラウザ)からの検索リクエストはHTTP GETメソッドで投入されるとする。このとき、リクエストパラメータ"q"に検索式が設定されることとする。たとえば、こんな具合である:



GET /search?q=lucene



すると、Luceneの検索サービスを提供しているWebアプリ側はqパラメータから検索式を取り出して検索し、検索結果をHTMLなどに整形してクライアントに返す。

次にその同じクライアントは、しばらくしてまたこんな検索リクエストを投げてよこすかもしれない:



GET /search?q=lucene



これは上とまったく同じリクエストなので、Luceneのインデックスが同じである限り(そして、ランダムに広告などを切り替え表示するのでもない限り)、先の結果と同じHTMLを出力して返すこととなる。

これはまったく無駄な処理だ。

このようなときに、クライアント側にキャッシュ機構があればそれを活用できるというHTTPの仕様がある。そこで、これをどのように実現するか考えてみよう。

クライアントのキャッシュを活用するには、検索結果をサーバから返すときに、Last-Modifiedというレスポンスヘッダをつけてクライアントに渡すようにする。Last-Modifiedにはインデックスの最終更新日を設定すればいいだろう。

すると、キャッシュ機構を持つクライアントは、同じ検索リクエストを発行するときにIf-Modified-Sinceというリクエストヘッダをつけて送ってくる。If-Modified-Sinceに設定されているのはLast-Modifiedで受け取ったインデックスの最終更新日である。

そこでサーバは、その日付とインデックスの更新日を比較し、インデックスの更新日が新しくなければ検索やHTML生成をせずに直ちに304(Not Modified)を返せばよい。304を受け取ったクライアントは、キャッシュ内のコンテンツを再利用するので、応答速度があがる。

具体的な実装方法はというと、サーブレットでgetLastModified()をインデックスの最終更新日を返すようにオーバライドするだけである。するとコンテナは、Last-Modifiedにこのコンテナの値を設定して返してくれる。さらにクライアントからIf-Modified-Sinceが送られてきたときにgetLastModified()を呼び出して日付を比較し、doGet()を呼んでHTMLを生成して返すか、doGet()を呼ばずに304(Not Modified)を返すかを自動的に判断する。

Luceneのインデックスの最終更新日の取得には、java.io.Fileクラスなどを使う必要はなく、インデックスに振られているバージョンを使うことができる。Luceneのバージョンのlong値はそのままDateに変換できる値であり、インデックスが作られた日時を表しているからである(Lucene本 P.108)。

JavaサーブレットとHTTPの仕様、およびインデックスのバージョンをうまく組み合わせることで、検索応答性能を大幅に上げることができる。サーバのCPUの節約にもなるので、負荷がそれなりにある状況下ではスループット(=QPS)の向上にも役立つだろう。
| 関口宏司 | Luceneパフォーマンス | 11:14 | comments(0) | trackbacks(1) |
商用検索エンジンとLuceneの比較
こんなことが言えるのは今だけなので言わせてもらおう。

「RONDHUIT 2.0」

最近は何にでも2.0をつけるのがはやっている。いや、流行はとうに過ぎていて、書いた後で自覚してしまうとちょっと自分が恥ずかしい。

書かなきゃよかった。

しかし、「RONDHUIT 2.0」とか言えるのは今だけだ。なのであえて書いてみた。

「RONDHUIT 2.0」の「2.0」は何のことかというと、会社が創立2年目に入った、ということである。先日、懇意にしている国産検索エンジンベンダーの人と飲んでいて、「そういえばRONDHUITも2年目だから2.0ですね」という話になったのであった。

2.0をつけると人は次に「じゃあ何が変わったんだ?」という話をする。火付け役はWeb 2.0だ。そしてその定義づけがされ、頭のいい人が解説本を書いてそれを読む人が出てきた。私は本を読んだクチだ。それもたくさん読んだ(ここにとりあげたのはその一部に過ぎない)。しかし結局、Web 2.0はさっぱりわからなかった。

私はRONDHUIT 2.0をそんなわからない話にはしたくなかったので、その飲み会のあとに酔った頭で何か具体的なわかりやすい定義がないか探してみたのだった。

そしてついにみつかった。それは「エンタープライズ分野への進出」である。

これまで表向きはLuceneを使って「Namazuリプレース」や「Googleリプレース」などといったサービスを提供してきた。これをRONDHUIT 1.0としよう。このレベルは、ドキュメント数で言うと数万件以下、いや、実態をもっと露骨に言うなら1千件にも満たないケースがほとんどである。

しかしこれまでの自分の仕事を振り返ってみると、数十万件や数百万件の文書を検索するシステム構築のコンサルをしてきたのだった。数百万件超の文書というのは、これは文書数だけでいえばエンタープライズといってもいいのではないだろうか。もちろん、文書数だけでエンタープライズの十分条件を満たすものではないが、サポートなんかもしっかり提供したりなんかして、エンタープライズっぽいのだ。

これはエンタープライズ分野に進出したといってもいいんじゃなかろうか。

そこで最近はエンタープライズへの対応、ということを意識して活動し始めている。

その第一弾が、レッドハットのJBossチームとのいろいろな活動だ。これはまだ会社対会社で協業しましょう、というような話ではないので声高に言うものではないのだが、「JBoss+Lucene(またはSolr)で大規模検索システムを構築できますよ」というシナリオで客先に営業をかけているという、現場レベルの話である。

そして、同じ話の流れで、ThinkITに「JBoss+Lucene」の記事を書くことになった。ThinkITには、現在、JBossチームから次のような記事がアップされている:

第1回:Red Hatが提供するJBoss Enterprise Middlewareとは
第2回:JBoss Enterprise Application Platformを操作する
第3回:JBoss Enterprise Application Platformのアーキテクチャを理解する
第4回:JBoss Web - Tomcatエボリューション

私の担当はもう少しあとの第9回から第12回である(変わる可能性もある)。

今のところ、こういった活動で地味に、しかし着実にエンタープライズへの道をLucene/Solrをかついで歩み始めたところだ。




そういったこともあり、会社のホームページもRONDHUIT 2.0に合うように改訂しようと準備中である。

まず、「Namazuリプレース」や「Googleリプレース」のページを廃止する。これがあるとどうやらLuceneが小規模のシステムでしか使えないのではないか、というような誤解を世間に生じさせるらしい。そんなことはないので、まずこのページを廃止することにした。そしてその代わりに商用検索エンジン(=検索エンジンベンダが販売している検索エンジン製品)とLucene(Solrを含む)の比較のページを作成する。なぜ商用検索エンジンと比較するかというと、最近は商用検索エンジンと競合になるケースがほとんどだからである。100%といってもいい。なので私が把握していない会社を含めると、商用検索エンジンとLucene/Solrを比較検討している企業は相当数に上ると考えられる。そういう会社には有益なページになるはずだ。

これまでの活動で、商用検索エンジンを使っている企業ユーザの体験談をいろいろ聞いてきたが、そういった経験から「これくらいなら書いてもよかろう」というものをまとめたものだ。

以下にその草稿のコンテンツを貼り付ける。編集をしていないので、図がないことや見出しがはっきりしないことなどの読みづらさはご了承いただきたい:




ロンウイットは、検索エンジンをお客様のシステムに組み込むサービスをご提供しています。特にエンタープライズ・レベルの大規模検索を得意としています。
ロンウイットのその他のサービス事例は、こちらをご覧ください。

「検索エンジン」には、オープンソース・ソフトウェアのLuceneまたはSolrを使用しています。したがって、ライセンス費用は一切不要です。導入費用のみのご負担で、お客様のシステムにエンタープライズ・サービス・レベルの検索エンジンを組み込むことが可能です。また、ご希望により別途追加で年間保守についても承ります。
⇒お見積もり・お問い合わせ

商用検索エンジンとLucene/Solrの比較のポイント

「無償検索エンジンは、商用検索エンジンと比較して見劣りするのではないか?」このような疑問を抱かれるのは当然です。そこで、実際に検索エンジンの比較ポイントをひとつずつあげてLucene/Solrがそれぞれのポイントでどのように評価されているか、確認してみましょう。

以下に、「検索エンジンを選択する際のチェックポイント」をご紹介します。これらは弊社がこれまでのコンサルティング活動を通じて集めた現場の視点で見たお客様のご意見をまとめたものです。

チェックポイント1:コストパフォーマンス

商用検索エンジンは小規模なものは数十万円、大規模なものになると数千万〜数億円ものライセンス費用がかかってきます。しかし、Lucene/Solrはエンタープライズ・レベルの大規模システムに対応できるだけでなく、ライセンス費用が不要です。そのため、浮いたお金を開発費用に充ててアプリケーションの機能の充実化や品質向上を図ったり、ハードウェア費用に充ててバックアップ体制を強化することなどが可能となります。

また、商用検索エンジンの中には高価なハードウェアを必須要件としているものがあり、これも導入時の費用を押し上げる原因となっています。Lucene/Solrはそのような特別なハードウェアを必要としません。

チェックポイント2:検索性能(処理速度)

検索エンジンの処理速度で最も重要かつ注目されるのが検索応答時間です。最新の検索エンジンはいずれも「転置索引」を作成して検索を実行する方式のため、単純な検索だと検索処理時間の差があまり出ません。

しかし、検索対象文書数が増えたり、検索式の複雑度が増したり、検索にヒットした文書数が増えたりした場合、検索エンジンによっては実用的なパフォーマンスが出ないものもあるため注意が必要です。

ロンウイットは、Lucene/Solrの動作特性を十分に理解したうえで導入コンサルティングを実施しております。そのため、最高の検索性能をお客様にご提供できるのです。

チェックポイント3:検索機能(基本的な検索機能の充実度)

開発するアプリケーションが要求する基本的な検索機能が検索エンジンに備わっているか、確認しましょう。検索機能の基本項目には次のようなものがります:

・単語検索とフレーズ検索
・AND/OR/NOT検索式、"()"を使った検索式、これらを組み合わせたBoolean検索式
・数値検索、日付検索、範囲検索
・ワイルドカード検索、正規表現検索、あいまい検索
・フィルタ検索


検索エンジンによってはこれらの一部をサポートしていないものもあります。また、フレーズを正確に扱えない検索エンジンも存在します。上記は検索の基本機能であり、これらのなかの一部の機能が欠けているということは、これらを組み合わせた応用的な検索式が構築できないことを意味します。このことは将来、お客様が提供するサービスの一部を変更したり、機能の提供自体をあきらめなければならなくなる可能性があることを示唆しています。

Lucene/Solrはフレーズの正確なハンドリングに加え、上記のすべてをサポートし、その上でこれらを組み合わせた複雑な検索式を高速に処理することができます。

チェックポイント4:ランキングとソートに対するカスタマイズの自由度

検索エンジンは、検索にヒットした文書のスコアを計算してランキング(検索結果の文書の表示順序)を決定します。

「ランキング」と「検索結果のソート」は、アプリケーション開発の全期間を通じて、お客様からカスタマイズの要求がもっとも多く出てくる部分です。したがって、ランキングとソートのカスタマイズの自由度が低い検索エンジンの選択は好ましくありません。

Lucene/Solrはランキングとソートのカスタマイズの自由度が非常に高い検索エンジンだといえます。以下にカスタマイズ可能なパラメータやカスタマイズの具体例をあげます:

・フィールドの重み付け(インデクシング時)や検索語の重み付け(検索時)を考慮した文書スコアによるランキング
・フィールドごとのソート(昇順・降順)(例:文字列、数値、日付など)
・任意の関数を用いた計算値の大小によるランキング
・位置情報によるソート(例:レストランを駅から近い順に表示するなど)
・検索語の文章中の位置によるランキング
・掲載料を多く支払っている有料顧客の企業情報の上位表示
・被リンク数の多いHTMLの上位表示
・検索のたびにランダムに並べる

チェックポイント5:日本語処理の柔軟性

検索エンジンの処理単位は「単語」です。しかし、スペースで単語が分かち書きされる英語などと違い、日本語は、文章から単語の区切りを見分けることが困難な言語です。そこで、日本語の文章からの単語抽出方法が重要になってきます。

現在、その方式には「形態素解析」と「N-gram」の2方式があります。これらの方式はそれぞれ一長一短があり、アプリケーションの要件に応じて選択できるのがベストです。また、アプリケーションの要件によっては、両方式を混在して使用できるのがよいでしょう。

しかし、ほとんどの検索エンジンは、どちらかひとつの方式しか採用していません。両方式が可能と謳う検索エンジンであっても「N-gram」が基本で、「形態素解析」はオプション料金を要求されたり、事例がないことから「N-gram」の利用を余儀なくされる場合もあります。

Lucene/Solrは、「形態素解析」と「N-gram」の両方式をアプリケーションの要件に応じて自由に選択できるほか、ひとつのアプリケーションでこれらを併用することも可能です。さらにそういった事例を持つ数少ない検索エンジンのひとつでもあります。

チェックポイント6:インデクシング性能(処理速度・リアルタイム更新・更新中の検索)

検索エンジンの処理性能のうち、検索時間の次に重要なのがインデクシング(転置索引の作成)に要する時間です。アプリケーションの要求時間内にインデクシングが終了することが重要ですが、場合によってはインデックスを複数に分けたり、分けたインデックスをマージしたり、運用設計を見直すことも行います。ロンウイットでは、Lucene/Solrの導入コンサルティングでこれらの点を考慮しながらお客様をサポートいたします。

検索エンジンによっては、リアルタイムのインデックス作成・更新ができなかったり、インデックス作成・更新中の検索ができなかったり、検索のスループットが落ちたり、機能制限があるものもありますが、Lucene/Solrにはこういった制限がありません。

チェックポイント7:スケーラビリティ・負荷分散・高可用性

ほとんどの商用検索エンジンは、サーバを複数配置することで、「スケーラビリティ」、「負荷分散」、「高可用性」への対応が可能です。

図1挿入(複数検索サーバ)

インターネットにサービスを公開しているWebアプリケーションでは、Webサイトの人気上昇に伴うユーザ数の増加があったときに、検索サーバを複数台配置して高負荷に対応することが緊急課題となります。しかし、サーバ台数やCPU数などでライセンス課金する一部の商用検索エンジン(※)では、サーバを複数台配置することはライセンス費用と保守費用の負担が増えることを意味します。このため、「商用検索エンジンの導入が原因で開発予算を割くことができず、必要なアプリケーション機能の開発を見送った」という事態にもなりかねません。

Lucene/Solrも、サーバを複数配置することで「スケーラビリティ」、「負荷分散」、「高可用性」に対応可能です。ライセンスは無償なので、サーバの複数台配置に必要な費用は、純粋にハードウェアの費用のみとなります。

※検索対象文書数やクエリレート(QPS)でライセンス課金するタイプの商用検索エンジンもあります。この場合はサーバ台数を増やしてもライセンス費用は変わりませんが、「商用検索エンジンを導入したがために、コンテンツを充実させることができない」という別の悩みも発生します。

チェックポイント8:オープン性とサポートの充実度

商用検索エンジンの場合、ソースコードは非公開が基本です(オープンソース・ソフトウェアをベースに開発されたものなどを除きます)。そのため、検索エンジンに不具合が発生した場合、その対処にはベンダーの協力が必要となってきます。ベンダーのサポートを受けるには、通常はシステム規模に応じた年間保守費用の支払いが必要となります。

Apache Software Foundationのもと開発されているLucene/Solrは、コミュニティーが運営するメーリングリストがサポートの基本となっています。しかし、常時大量のコンテンツを保有・メンテナンスし、多数のユーザ向けに日々最新の情報を提供している企業にとって、ボランティアベースのコミュニティによるサポートだけでは不安があります。そこでロンウイットでは、このようなエンタープライズ分野でのLucene/Solrの利用を促進するべく、有償サポートサービスをお客様にご提供しております。

ロンウイットのサポートサービスでは、以下のような活動を行っております:

・Lucene/Solrに関するQ&A対応
・お客様サイトで発生した不具合の原因究明と回避策のご提案
・お客様サイトで発生した不具合のコミュニティーへの報告
・修正パッチの作成およびコミュニティーへのフィードバック
・コミュニティで発見・報告された重大なバグのお客様へのご連絡
・新機能の開発とコミュニティーへのフィードバック
・新バージョンやコミュニティに提案された新機能の調査とご報告

図2挿入(コミュニティ+RH+お客様)

「不具合への対処」という観点でLucene/Solrと商用検索エンジンを比較すると、Lucene/Solrはオープンソース・ソフトウェアであるために、「最悪でも自分で直せる」という安心感があります。一方、商用検索エンジンの不具合対応はベンダに依存するため、ベンダの協力姿勢が重要な判断材料となります。

チェックポイント9:ツールの充実度

以上の検索エンジンとしての基本機能に加え、その他のツール類の充実度も検索エンジンを使って開発するサービスの使い勝手を左右する重要な判定材料となります。

オープンソース・ソフトウェアであるLucene/Solrは、世界中の開発者が開発したツールが日々コミュニティに提案されており、よいものは取り込まれていくしくみになっています。したがって、ツール類も非常に充実しています。以下その一部をご紹介します:

・インデックスブラウザGUIや管理画面。
・ハイライト機能。これにより、検索結果一覧画面にて、文書から要約を抽出・検索語を強調した状態で要約文を表示できます。

図3挿入(ハイライト)

・ファセット検索。これにより、検索結果画面に絞り込み検索用のリンクを自動表示し、クリックだけの簡単操作でユーザを目的の文書(商品情報など)にすばやく誘導できます。ユーザに複雑な検索式を入力させることなく、さまざまな切り口(文書の任意の属性)による絞り込み検索を実行可能にします。

図4挿入(ファセット検索)

・表記のゆれや類義語を考慮した検索機能。これにより、「引越し」で「引っ越し」を含む文書を検索したり(表記のゆれ対応)、「首相」で「内閣総理大臣」を含む文書を検索する(類義語対応)ことができます。
・RDBクローラとCSVクローラはSolrに付属しています。その他のさまざまなクローラはロンウイットがコンサルティングサービスの中でお客様にご提供します。

商用検索エンジンの中には、ツールに対してオプション料金を要求するものもあり、注意が必要です。

チェックポイント10:開発のしやすさ

LuceneはJavaで書かれているため、Luceneを使ったアプリケーションはJavaで書く必要があります。しかし、Luceneの転置索引のフォーマットは公開されているため、Java以外のプログラミング言語を使ったLuceneポーティングが存在しています(C#やPythonなど)。したがって、開発チームのメンバーは使い慣れたプログラミング言語を選択することが可能です。

SolrもJavaで書かれているため、Solrプラグインの開発はJavaで行う必要があります。しかし、Solr自身は検索リクエストをHTTPリクエストで受け取り、検索結果をXMLで返す検索サーバとして機能しますので、フロントサーバをPHPやRuby on Railsで開発する、といったことも可能です。

図5挿入(RoR+Solr)


エンタープライズ向けの検索エンジン - Lucene/Solr

以上ご説明したとおり、Lucene/Solrは大規模システムの高負荷に耐えうる高性能の検索エンジンです。そしてロンウイットは、お客様のご要望や状況に合わせて検索エンジンを導入し、お客様が安心して運用できるようにLucene/Solrに関するコンサルティングサービスとサポートサービスをご提供しております。

エンタープライズ・レベルの検索エンジンとサービスを、ぜひご検討ください。
⇒お見積もり・お問い合わせ
| 関口宏司 | Luceneとは? | 00:01 | comments(0) | trackbacks(3) |
現trunkでより速くなったLuceneのインデクシング処理
Luceneのインデックス作成処理性能は進歩を続けている。現在のtrunkのパフォーマンスはかなりあがっている。

グラフは10のユニークワードからなる1つのフィールドを持つドキュメントを1万件登録したときの処理時間をプロットしたものである。Lucene 2.0、2.1、2.2およびtrunkで計測した。

インデックス作成時間比較

バージョンがあがるほどだいたい速くなっているが、特に現trunkでの処理時間の短縮が際立っている。

なお、trunkバージョンからFieldクラスにsetValue()というメソッドが追加された。このメソッドを使うと、Fieldインスタンスをnewせずに使いまわすことができる。そのため、GCの発生を抑制し、結果的にパフォーマンスの向上に貢献するようである。

今回の簡単なテストではその効果があまり見られなかったのでグラフには掲載していないが、プログラムによっては効果があるかもしれない。
| 関口宏司 | Luceneパフォーマンス | 02:18 | comments(0) | trackbacks(0) |
+ Solrによるブログ内検索
+ PROFILE
      1
2345678
9101112131415
16171819202122
23242526272829
30      
<< September 2007 >>
+ LINKS
検索エンジン製品 - 比較のポイント
商用検索エンジンを購入した企業担当者は読まないでください。ショックを受けますから・・・
>>製品比較 10のポイント
+ Lucene&Solrデモ
+ ThinkIT記事
+ RECOMMEND
Apache Solr入門 ―オープンソース全文検索エンジン
Apache Solr入門 ―オープンソース全文検索エンジン (JUGEMレビュー »)
関口 宏司,三部 靖夫,武田 光平,中野 猛,大谷 純
+ RECOMMEND
Lucene in Action
Lucene in Action (JUGEMレビュー »)
Erik Hatcher,Otis Gospodnetic,Mike McCandless
FastVectorHighlighterについて解説記事を寄稿しました。
+ RECOMMEND
+ SELECTED ENTRIES
+ RECENT COMMENTS
+ RECENT TRACKBACK
+ CATEGORIES
+ ARCHIVES
+ MOBILE
qrcode
+ SPONSORED LINKS