2

150万のドキュメントを含むRAMDirectoryがあり、PrefixQueryを使用して単一のフィールドを検索しています。検索テキストの長さが3文字以上の場合、検索は非常に高速で、20ミリ秒未満です。ただし、検索テキストの長さが3文字未満の場合、検索に1秒かかる場合もあります。

これはオートコンプリート機能であり、ユーザーは1文字で開始するため(実際には1文字の長さの結果があります)、検索テキストの長さを制限することはできません。

コードはほとんど次のとおりです。

var symbolCodeTopDocs = searcher.Search(new PrefixQuery(new Term("SymbolCode", searchText), 10);

SymbolCodeはNOT_ANALYZEDフィールドです。Lucene.NETのバージョンは3.0.3です。

例は単純化されており、実際のシナリオで追加の制約を適用するにはBooleanQueryを使用する必要があるかもしれません。

この特定のケースでパフォーマンスを向上させるにはどうすればよいですか?これらの1文字または2文字のクエリにより、サーバーがダウンします。

4

1 に答える 1

2

まだ行っていない場合は、インデックスからストップ ワードを削除することを検討してください。

ストップ ワードがどのように PrefixQuery を遅くするかを理解するには、PrefixQuery がどのように機能するかを考えてください。これは、PrefixQuery の用語で始まるインデックスのすべての用語を含む BooleanQuery として書き直されます。たとえば、これまでのところこれa*a OR and OR aardvark OR anchor OR ...悪くなく、数千の用語でも驚くほどうまく機能します。本当の無駄は、インデックス内のすべてのドキュメントで何度も見つかる可能性が高いため、aandのようなストップ ワードが含まれている場合です。andこれにより、検索の収集/収集/スコアリング部分の作業がさらに多くなり、処理が遅くなります。

余談ですが、純粋に使いやすさの観点から、ユーザーが入力した文字数が 2 ~ 3 文字未満の場合は、オートコンプリート検索を実行しないことを強くお勧めします。結果がまったく関連性があるとは想像できません。検索を実行することを想像してみてa*ください。どの結果がより関連性が高いかを判断する方法はありません。ユーザーに何かを表示する必要がある場合は、コメントで提案されている Jf Beaulac のような n-gram アプローチを検討してください。

于 2012-12-28T14:16:26.080 に答える