2011-06-24 12 views
15

「Lucene in Action 2nd Edition」を読んでいるうちに、Luceneの結果フィルタリングに使用できるFilterクラスの説明が出ました。 Luceneは多くのフィルタを繰り返していますQueryクラス。たとえば、NumericRangeQueryおよびNumericRangeFilterです。{Filter}はLuceneで{Query}より高速ですか?

NRFNRQとまったく同じですが、文書の採点はありません。つまり、の場合は、のスコアリングや、文書の並べ替えをの文書フィールド値にする必要はありません。Filterは、パフォーマンスの観点からはQueryです。

+0

は、ローカルまたは別のサーバー上のデータベースですか? –

+0

データベースはローカルに格納されています。いくつかのサーバー上にはSSDドライブもあります。 –

答えて

12

私はウーヴェ・シンドラーから素晴らしい答えを受け、私はここでそれを再投稿してみましょう。

あなたはキャッシュ・フィルターをいけない場合はLuceneでConjunctionScorer は、現在のフィルターに使用されていない最適化を、持っているとして、クエリは、速くなります。 フィルタをキャッシュしても問題ありません(たとえば、すべてのクエリに適用される特定のユーザーに対して常に同じアクセス制限がある場合)。その場合、 では、フィルタは一度だけ実行され、それ以降のすべての 要求に対してキャッシュされ、クエリ結果セットと交差します。

ランダムに「フィルタ」する。たとえば、レンジクエリや同様のもの(MultiTermQueries と呼ばれる)が フィルタのような同じBitSetアルゴリズムでも実装されているとします( )。 - 実際にはScorer-implでラップされたフィルタのみです)。ただし、 (ConjunctionScorer)クエリと「フィルタ」クエリを一緒にANDsする スコアラーは、検索後に フィルタを適用するコードよりも一般的に高速です。これは、いくつかの改善が可能かもしれないが、一般的に フィルタは、本当にもう必要ありませんLuceneの中で何かしているので、 がすでにフィルタを作るためにいくつかのアプローチだったと同じに照会し、そして ではなく、その後も非スコアリングクエリをキャッシュすることができます。これにより、多くのコードが簡単に になります。私はそれに取り組んでいます - 彼らは得点する前に文書をフィルタリングするIndexReaderの岩下差し込ま 、 ですが、それはまだ( https://issues.apache.org/jira/browse/LUCENE-3212を参照)を実装していない場合

フィルタは、Luceneの4.0を持つ巨大な速度向上をもたらすことができます。また、 は、フィルタをランダムアクセス(ビットセットとして簡単です)することもできます。 は、クエリ後のフィルタリングも改善できます。しかし、私はさらに をクエリします(もし がFieldCacheだけに基づいているクエリのように)それらがサポートできるならば、部分的にランダムアクセスを問い合わせます。

ウーヴェ

1

フィルタを再利用する場合は、キャッシング目的のためにクエリの代わりにこれを使用することをお勧めします。スコアリングやフィールドの値を使用しない場合は、フィルタオーバークエリを使用することもできます。

これが役に立ちます。

8

Dennisの回答:いいえとは対照的に、同じクエリを複数回再利用する場合を除き、おそらくフィルタを使いたくないでしょう。

for each document in index: 
    if document matches query: 
     match[i] = 1 
    else 
     match[i] = 0 

だから、それは通常のクエリのようなあなたのインデックスの代わりに、対数時間にわたり線形時間で実行されます:

A NumericRangeFilterはただ、基本的に、それはこのような何かを行うことを意味MultiTermQueryWrapperFilterのサブクラスです。

さらに、フィルタはより多くのメモリを消費します(インデックス内の各ドキュメントごとに1ビット)。

同じクエリを何度も繰り返し使用している場合は、パフォーマンス/メモリヒットを1回支払って後で使用する方が高速になるほど価値があります。しかし、それが一回限りのクエリであれば、それはそれほど価値のあるものではありません。

(あなたはそれを再利用するつもりなら、フィルタがキャッシュされているように、また、CachingWrapperFilterを使用しています。)

1

は、私はフィルタではなく、クエリを使用することをお勧めているようだhttp://wiki.apache.org/lucene-java/ImproveSearchingSpeedでこれを見つけました。直感的には、同じことをする必要があるので、私にはもっと意味があります。唯一の違いは、フィルターがスコアで使われていないということです。

フィルタの使用を検討してください。 の結果を、クエリ節を使用するよりもキャッシュされたビットセットフィルタ ではなく、インデックスの一部に制限する方がはるかに効率的です。これは、大きなインデックスの多数のドキュメントと一致する制限 の場合に特に当てはまります。フィルタは通常結果をカテゴリに限定するのに通常使用される ですが、多くの場合、クエリ句を置き換えるのに多くの場合使用できます。クエリとフィルタを使用する の1つの違いは、クエリが スコアに影響を与え、フィルタは影響を受けないことです。

関連する問題