2011-02-07 7 views
9

Luceneの特定のクエリのすべての結果を数える最速の方法は何ですか?Lucene(java)のすべての結果を数える最速の方法

  1. TopDocs.totalHits
  2. はコレクター」を数えるのカスタムを実装QueryFilter
  3. を使用して、フィルターを実装し、管理します。これは、単にcollect(int doc)メソッドのカウントをインクリメントし、acceptsDocOutOfOrder()メソッドに対してtrueを返します。他の方法はすべてNOOPSです。

1.私はすべてのドキュメントでスコアリングを行います。2. FieldCacheの読み込みによって先行攻撃を受ける可能性があるので、答えは3と仮定します。Luceneはこのようなコレクタからのコレクタ?

答えて

1

あなたは#3が速くなるのは正しいですが、私はそれが得点のためではないと思います。はるかに速い方法があります、あなたがこれの背後にある推論を気にしない場合は、一番下までスキップしてください。

#1のパフォーマンスの低下は、TopDocsコレクタが優先度キューにドキュメントを保持することに起因します。つまり、スコアでソートするのに時間がかかります。 (あなたもメモリを少し食べますが、int + floatのヒープだけを格納しているので、おそらく最小限に抑えられています)

Luceneがこれをデフォルトで提供しない理由は、すべての結果を探したくない。だからこそあなたが検索するとき、あなたはトップが見つかると言うだけですn結果。これにはstrong theoretical reasonsがあります。 Googleでも「のうちの25を表示すると約件の結果が表示されます。

あなたの忠告は次のとおりです。妥当な数の結果がある場合は、TopDocs.totalHitsを使用すると、パフォーマンスが悪化することはありません。 totalHitsメソッドで問題が発生した場合、私はカスタムコレクターがはるかに良いとは思わない。 (TopDocs.totalHitsはn回n回実行され、カスタムコレクタは線形になります。設定によっては、log n係数が関係する場合もありません)

この機能とTopDocs.totalHitsが遅すぎる場合は、検索語句の文書頻度を調べることをおすすめします。あなたは周波数が独立していると仮定することができるので(p(AとB)= p(A)* p(B))、そこからかなり良い推測をする。これは非常に高速です。なぜなら、各用語の定時検索ですからです。

+0

感謝。この段階でTotalHitCountCollectorを使用します。私たちのデータセットはまだ正確にカウントするのに十分です。私はあなたが念頭に置いて言葉の周波数のアプローチを維持します - それは実際に最も速いアプローチを聞いています。 – npellow

+0

私はGoogleがこれをやっているのだろうか。明らかに「トップ25」の結果を返すわけではありません。そうであれば、他のすべての結果を調べて、彼らがトップ25にいないことを発見する副作用として結果の総数を知るべきである。私の理論は、トップ "の結果をアップ。 – Trejkaz

関連する問題