在Solr / Lucene中查询相等性

时间:2013-07-18 07:20:52

标签: solr lucene normalization solrj

问题:

尝试识别2个不同的查询实际上是相同的。

例如:

field1:[1 TO 3] OR field1:5

实际上与查询相同:

field1:5 OR field1:1 OR field1:3 OR field1:2

想法:

有没有办法将查询规范化为某种规范形式,以便在规范化后,简单的字符串比较就可以了?

例如,使用上面的示例,两个查询都可能变为:

field1:1 OR field1:2 OR field1:3 OR field1:5

然后可以简单地比较以确定它们是否相等。

或许实际上存在某种能够确定两个查询是否相等的服务。我找不到任何。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

主要问题是那些真的不完全相同。

field1:[1 TO 3]是范围查询,它可以表示字段上的字典范围,在这种情况下它将匹配field1:2abcde,或者可以表示浮点字段上的数字范围,其中如果它匹配field1:1.234。另一个查询field1:1 field1:2 field1:3只能匹配三个指定的值,因此这两个示例都不会匹配。

此外,由于字段可能是多值的,因此field1:1 field1:2 field1:3中不止一个字符可能在同一文档中匹配,这会使每个字段的评分不同。

考虑一个更简单的情况,我们可以合理地确定的两个查询是如何相同的,例如:

  • field2:this field1:that
  • field1:that field2:this

这些肯定是相同的,至少是StandardQueryParser

通过查询解析器运行查询后,您将拥有Query。将最终查询转换回字符串往往不能很好地工作,因为查询解析器语法不能表达任何类型的查询对象(Query.toString()最适合用于调试,真的)。

因此,您需要比较Query个对象。

我相信,Query.rewrite()的输出最容易比较。这将为您提供一组原始查询。这将为范围查询提供所需的TermQueries,因此它会通过与初始查询相关的问题而不知道字段内容。

QueryIndexReader都不会在查询之间实现任何形式的直接比较。据我所知,你需要提供比较器。这将涉及比较任意复杂的嵌套原始查询集(原始查询包括:BooleanQueryConstantScoreQueryCustomScoreQueryDisjunctionMaxQueryFilteredQuery,{{1 }},MatchAllDocsQueryMultiPhraseQueryMultiTermQueryPhraseQuerySpanQueryTermQuery


真正的问题不在于查询本身是否完全相同,我们已经确定它们不是。我认为,更有意义的问题是它们与索引中的数据相同。考虑到这一点,一个更简单的实现是搜索每个查询,并比较每个结果集(ValueSourceQuery)中的文档编号(可能还有得分?)。