尝试识别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
然后可以简单地比较以确定它们是否相等。
或许实际上存在某种能够确定两个查询是否相等的服务。我找不到任何。
感谢您的帮助。
答案 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,因此它会通过与初始查询相关的问题而不知道字段内容。
Query
和IndexReader
都不会在查询之间实现任何形式的直接比较。据我所知,你需要提供比较器。这将涉及比较任意复杂的嵌套原始查询集(原始查询包括:BooleanQuery
,ConstantScoreQuery
,CustomScoreQuery
,DisjunctionMaxQuery
,FilteredQuery
,{{1 }},MatchAllDocsQuery
,MultiPhraseQuery
,MultiTermQuery
,PhraseQuery
,SpanQuery
,TermQuery
)
真正的问题不在于查询本身是否完全相同,我们已经确定它们不是。我认为,更有意义的问题是它们与索引中的数据相同。考虑到这一点,一个更简单的实现是搜索每个查询,并比较每个结果集(ValueSourceQuery
)中的文档编号(可能还有得分?)。