Lucene インデックス内で上位の用語を取得できることはわかっていますが、Lucene インデックスのサブセットに基づいて上位の用語を取得する方法はありますか?
つまり、特定の日付範囲内のドキュメントのインデックスで上位の用語は何ですか?
Lucene インデックス内で上位の用語を取得できることはわかっていますが、Lucene インデックスのサブセットに基づいて上位の用語を取得する方法はありますか?
つまり、特定の日付範囲内のドキュメントのインデックスで上位の用語は何ですか?
理想的には、これを行うためのユーティリティがどこかにあるはずですが、私はそれを知りません。ただし、これを合理的に効率的な方法で「手動」で行うのはそれほど難しくありません。対象のサブセットを定義するために使用できるQuery
and/orオブジェクトが既にあると仮定します。Filter
まず、インデックス サブセット内のすべてのドキュメント ID のリストをメモリ内に作成します。を使用IndexSearcher.search(Query, Filter, HitCollector)
すると、これを非常に迅速に行うことができます。HitCollector
ドキュメントには、動作するはずの例が含まれています。または、他のコンテナを使用してドキュメント ID を保存することもできます。
次に、空の HashMap (または何でも) を初期化して用語を合計頻度にマップしIndexReader.getTermFreqVector
、関心のあるすべてのドキュメントとフィールドのメソッドの 1 つを呼び出してマップに入力します。引数が 3 つの形式の方が単純に見えますが、どちらでもかまいません。引数が 3 つの形式の場合、メソッドがマップ内にあるかどうかをチェックし、そうでない場合は関連付け、そうである場合は既存の値に追加TermVectorMapper
するメソッドを作成します。ループ内のドキュメントごとに新しいオブジェクトをインスタンス化するのではなく、このパス内のすべての呼び出しで同じオブジェクトを使用するようにしてください。andをオーバーライドすることで、かなり高速化することもできます。あなたのオブジェクトはそれらの両方に対して返されるはずです。それはあなたのように見えますmap
term
frequency
frequency
TermVectorMapper
getTermFreqVector
isIgnoringPositions()
isIgnoringOffsets()
true
TermVectorMapper
メソッドの定義を強制されることもありますsetExpectations
が、何もする必要はありません。
マップを作成したら、頻度の高い順にマップ アイテムを並べ替えて、好きなだけ多くの上位用語を読み上げます。必要な用語の数が事前にわかっている場合は、O( n log n ) ソートを使用する代わりに、線形時間で上位k 個のアイテムを見つけるために、ある種の派手なヒープベースのアルゴリズムを実行することを好むかもしれません。私は、普通の古いソートが実際にはかなり速いと思います。しかし、それはあなた次第です。
HitCollector
必要に応じて、直接呼び出すことで最初の 2 つのステージを組み合わせることができますgetTermFreqVector
。これは確かに同じように正しい結果を生成するはずであり、直感的にはよりシンプルで優れているように見えますが、ドキュメントでは、2 パス アプローチよりもかなり遅くなる可能性があると警告しているようです (HitCollector の例と同じページ)。その上)。または、彼らの警告を誤解している可能性があります。野心的である場合は、両方の方法を試して比較し、お知らせください。
TermVectors のカウントアップは機能しますが、反復するドキュメントが多数ある場合は遅くなります。また、最上位用語で docFreq を意味する場合は、用語をバイナリとしてカウントするだけで、TermFreqVector でカウントを使用しないでください。
または、ファセット数などの用語を繰り返すこともできます。すべての用語に対してキャッシュされたフィルターを使用します。それらのBitSetは高速交差カウントに使用できます。