评分看似等效的Solr查询之间的差异

时间:2013-07-10 13:18:03

标签: java solr lucene

据我了解Solr's scoring function,以下两个查询应该是等效的。

即,语料库中的每个文档score(q1, d) = score(q2, d)都有d

查询1:evolution OR selection OR germline OR dna OR rna OR mitochondria

查询2:(evolution OR selection OR germline) OR (dna OR rna OR mitochondria)

查询显然在逻辑上是等效的(它们都返回相同的文档集)。此外,两个查询都包含相同的6个术语,并且每个术语在两个查询中都增加1。因此,每个术语应该对总分有相同的贡献(相同的TF,相同的IDF,相同的提升)。

尽管如此,查询不会给出相同的分数

通常,术语(a OR b OR c OR d)的组合与查询的组合((a OR b) OR (c OR d))不同。两种类型的查询之间的语义差异是什么?是什么导致他们导致不同的评分?

我问的原因是我正在构建一个自定义请求处理程序,我在其中构造第二种类型的查询(查询的结合),而我可能实际上需要构造第一种类型的查询(条款的结合) 。换句话说,这就是我正在做的事情:

Query q1 = ... //conjunction of terms evolution, selection, germline
Query q2 = ... //conjunction of terms dna, rna, mitochondria
Query conjunctionOfQueries = new BooleanQuery();
conjunctionOfQueries.add(q1, BooleanClause.Occure.SHOULD);
conjunctionOfQueries.add(q2, BooleanClause.Occure.SHOULD);

虽然也许我应该这样做:

List<String> terms = ... //extract all 6 terms from q1 and q2
List<TermQuery> termQueries = ... //create a new TermQuery from each term in terms
Query conjunctionOfTerms = new BooleanQuery();
for (TermQuery t : termQueries) {
    conjunctionOfTerms.add(t, BooleanClause.Occure.SHOULD);
}

1 个答案:

答案 0 :(得分:4)

我跟着femtoRgon's advice检查了分数计算的调试元素。我发现的是计算确实在数学上是等价的。唯一的区别是在 query-of-queries 计算中我们存储了中间结果。更确切地说,我们将对每个子查询的总和的贡献存储在变量中。显然,为了存储中间结果而停止会产生累积数值误差的效果:每次我们存储中间结果时,我们都会失去一些准确性。由于应用程序中的实际查询非常大(不像简单的示例查询),因此丢失的准确性很高,累积的错误有时甚至会改变返回文档的排名顺序。

因此,词汇连接查询的排名要比的查询结合查询稍微好一些,因为的结合 - -queries 查询会累积更大的数字错误。