0

私はある種の特別な問題を抱えています(少なくとも私はそれが1つだと思います^^)。私がやりたいことを説明できるといいのですが。

一連の用語(文字列)があり、各用語にもスコア(double)があります。これらの用語を私のluceneインデックスのドキュメントと一致させたいと思います。

しかし、私はこれらの用語のすべての可能な組み合わせを検討したいと思います。最初の私のアイデアは、単にジャイアントを構築することでした

`BooleanQuery: field1:term1 OR field1:term2 .... OR field2:term1 OR field2:term2 ...`

ただし、このクエリはもちろん、用語ごとに個別のクエリを生成するのと同じ結果を返しません。

`Query1: field1:term1 OR field2:term1 ...`
`Query2: field1:term2 OR field2:term2 ...`

問題は、私のアプリケーションがir-applicationであり、これらの用語が自動的に生成/抽出され、どの用語を一緒に検索するか、単独で検索するかがわからないことです。だから私は「両方の長所」を持ちたいと思っています。

用語リストのすべての可能な組み合わせを検索するクエリを作成する方法はありますか?

もちろん、いくつかのループを作成して、考えられるすべての組み合わせに対してクエリを生成することもできますが、それはおそらく永遠に実行されます...

あなたが私が欲しいものを理解し、私を助けることができることを願っています:)ありがとう!

4

2 に答える 2

1

必要な最終結果セットが何であるかはよくわかりませんが、いくつかの可能性があります。

いずれかの用語に対して検索フィールドのすべての一致が必要な場合は、次のようにします。

field1:term1 OR field1:term2 .... OR field2:term1 OR field2:term2 ...

または

field1:term1 field1:term2 .... field2:term1 field2:term2 ...

完全に適切です。

使用可能なすべての用語に少なくとも1つ一致する結果のみが必要であるが、検索されたフィールドが必要な場合は、次のようにクエリを構成できます。

+(field1:term1 field2:term1) +(field1:term2 field2:term2) ...

または、ここで検索するフィールドを1つの検索可能なフィールドにマージして、一緒に検索するのをはるかに簡単にすることもできます。ただし、これを実現するためのより良い方法であるかどうかは、アプリケーションによって異なります。


1つの用語が検索結果を支配しないようにクエリを調整する限り、次のようになります。

クエリを調整するための最初のステップは、特定の用語が結果を支配している理由を見つけることだと思います。その鍵となるのは、使用方法を学ぶことです:IndexSearcher.explain(query、doc)。これにより、ドキュメントのスコアリング方法が説明されます。Lukeは、インデックスに対してクエリを試行し、ドキュメントがスコアを取得する理由を確認するための優れたインターフェイスを提供します。

また、TFIDFSimilarityは、デフォルトでスコアを計算するDefaultSimilarityクラスの主要部分を文書化します。そこにあるドキュメントは、Luke / Explain(query、doc)に表示されるスコアリングパラメーターの特定の側面を理解するのに役立ちます。

問題についての私の最もよい推測は、あなたが複数の分野で同じ共通の用語にぶつかっているかもしれないということです。これにより、検索された各フィールドのその用語のスコアが複合され、1つのフィールドにのみ表示される用語の結果が消去される可能性があります(ただし、あなたの場合は同じように関連する可能性があります)。その場合、DisjunctionMaxQueryを使用して同じ用語を検索する複数のフィールドをラップすることで修正できます。

例えば:

BooleanQuery root = new BooleanQuery()
DisjunctionMaxQuery dismax1 = new DisjunctionMaxQuery(1.1);
dismax.add(new TermQuery(new Term("field1", "term1")));
dismax.add(new TermQuery(new Term("field2", "term1")));
//etc
root.add(dismax1, BooleanClause.occur.SHOULD);
DisjunctionMaxQuery dismax2 = new DisjunctionMaxQuery(1.1);
dismax.add(new TermQuery(new Term("field1", "term2")));
dismax.add(new TermQuery(new Term("field2", "term2")));
//etc
root.add(dismax2, BooleanClause.occur.SHOULD);
于 2013-01-21T22:20:21.963 に答える
0

これが役立つかどうかはわかりませんが、すべてのフィールドから情報を取得して、別の単一のフィールドに複製することができます。

冗長であることはわかっていますが、ディスク容量に問題がなければ、クエリを実行する方が便利なため、クエリは次のようになります。

aggr_field:(term1 OR term2 OR term3)
于 2013-01-22T09:46:03.010 に答える