2013-01-21 51 views
0

我有一种特殊问题(至少我认为它是一个^^)。我希望我能描述我想要做的事情:Lucene - 在索引中搜索一组单词

我有一套条款(字符串),每项也有一个分数(双)。 我现在想要将这些条款与我的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 ...` 

的问题是,我的应用程序是一个红外应用程序,这些条款是自动生成/提取的,我不知道,应该一起搜索哪些条款或单独更好。所以我想拥有“两全其美”。

有没有一种方法可以查询我的术语列表的所有可能的组合?

我当然可以做一些循环,并为每一个可能的组合查询,但将永远可能运行...

希望你明白我想要什么,能不能帮我:)谢谢!

回答

1

不太清楚你想要的最终结果集是什么,但这里有几个可能的原因:

如果你只是想在任何每场比赛搜索方面对这些词的话:

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

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

是完全足够的。

如果你只是想要有上所有可用的条件至少有一个匹配的结果,但在任何搜索领域,那么你可以构建这样的查询:

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

或者,可以合并域你想在这里搜索到一个可搜索的字段,使他们更容易一起搜索。不过,这是否是更好的方法取决于您的应用程序。


至于调整你的查询,以防止一个长期主宰你的搜索结果:

我认为有关调整的查询是找出为什么某些方面有支配你的结果的第一步。关键是要学会使用:IndexSearcher.explain(query,doc)。这将解释如何评分文件。 Luke提供了一个很好的界面来对索引进行查询,并了解为什么文档能够得到他们所做的分数。

此外,TFIDFSimilarity还记录了默认情况下计算分数的DefaultSimilarity类的主要部分。那里的文档将有助于理解Luke/explain(query,doc)中显示的评分参数的某些方面。

我在这个问题上最好的猜测是,你可能在多个领域中使用相同的通用术语。这将在每个字段中找到该字段的分数,并且可以消除只出现在一个字段中的字词的结果(但在您的情况下可能同样相关)。在这种情况下,您可以通过将多个字段用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); 
+0

运行查询,我可能不知道我想要什么太大^^。我的问题是,当我在一个查询中搜索所有条款(与OR相关)时,有些词主宰了结果。意味着前n个结果完全基于其中一个关键字。但是,如果我对每个术语进行单独查询,我将放弃可能由于合并一些术语而导致的(也许是现有的)利益。我知道这是预期的行为,但我希望有一些我错过的魔术。 – dburgmann

+0

更新了我的回答,提供了一些关于理解和调整评分的提示。 – femtoRgon

0

不知道这会有所帮助,但你可以从所有领域采取的信息,并在另一单场复制它们。

我知道它是多余的,但如果磁盘空间不是问题,它可能是更方便的让你的查询变得

aggr_field:(term1 OR term2 OR term3)