【问题标题】:Scoring difference between seemingly equivalent Solr queries看似等效的 Solr 查询之间的得分差异
【发布时间】:2013-07-10 13:18:03
【问题描述】:

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

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

查询一: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);
}

【问题讨论】:

  • 您是否尝试在结果中获得explain?我想知道查询解析器是否会产生与您预期的略有不同的查询。
  • @femtoRgon:谢谢,您的评论有助于找到答案。有兴趣的请看下文。

标签: java solr lucene


【解决方案1】:

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

所以 conjunction-of-terms 查询的排名应该比 conjunction-of-queries 查询略好,因为 conjunction-of -查询查询累积了更大的数值错误。

【讨论】:

  • +1 这真的很有趣。因此,作为一个好的经验法则,我们应该尝试在没有不必要的括号的情况下表达搜索条件。
猜你喜欢
  • 2019-01-14
  • 2022-10-14
  • 2021-08-16
  • 2016-06-17
  • 2012-04-07
  • 2014-06-20
  • 2012-12-07
  • 2013-02-14
相关资源
最近更新 更多