0

我有一种特殊的问题(至少我认为是一个^^)。我希望我能描述我想做的事情:

我有一组术语(字符串)每个术语也有一个分数(双)。我现在想将这些术语与我的 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 应用程序,这些术语是自动生成/提取的,我不知道应该一起搜索哪些术语,还是单独搜索更好。所以我想拥有“两全其美”。

有没有办法让查询搜索我的术语列表的所有可能组合?

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

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

4

2 回答 2

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);
于 2013-01-21T22:20:21.963 回答
0

不确定这是否会有所帮助,但您可以从所有字段中获取信息并将它们复制到另一个字段中。

我知道这是多余的,但如果磁盘空间不是问题,运行查询可能会更方便,这样你的查询就变成了

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