测试Lucene查询是否匹配所有文档

时间:2013-12-04 09:21:19

标签: java solr lucene

给定Query的实例是否有可能以某种方式检查该实例是否恰好代表始终匹配索引中所有文档的查询?

例如,包含MatchAllDocsQuery子句的BooleanQueryMatchAllDocs是始终返回所有文档的查询。另一个例子是BooleanQuery,它有一个SHOULD-match子句,它有一个嵌套的SHOULD-match子句,里面有MatchAllDocs

请注意,由于其中包含所有可能的术语或因为索引为空而发生返回所有内容的查询不会计为始终返回所有文档的查询。换句话说,无论索引包含什么,我都想检查给定查询是否总是返回所有内容。

是否可能或至少近似可能?如果解决方案适用于可以从Solr's Extended Dismax Query Parser返回的任何查询,我会接受一个解决方案,该解决方案对任何可能的情况都不起作用。

2 个答案:

答案 0 :(得分:1)

包含BooleanQuery作为其中一个条款的MatchAllDocsQuery并不一定会返回所有文档,因为BooleanQuery也可能包含其他MUST或{{1}限制结果集的子句。我不认为这有什么可以做到这一点,并试图处理Solr可能分裂的任何类型的查询将是困难的。您需要递归地遍历查询以确保一切有效地减少到MUST_NOT,忽略分数。

类似的东西(此时完全未经测试):

MatchAllDocsQuery

如果您还希望处理org.apache.lucene.queries中的内容,则可以处理更多查询类型,例如boolean willMatchAll(Query query) { if (query instanceof MatchAllDocsQuery) return true; } else if (query instanceof BooleanQuery) { boolean foundMatchAll = false; for (BooleanClause clause : ((BooleanQuery)query).getClauses()) { if (clause.isProhibited()) { return false; //A reasonable assumption, that the MUST_NOT clauses won't be empty } else if (clause.isRequired()) { if (willMatchAll(clause.getQuery())) { foundMatchAll = true; } else { return false; //any MUST clause that is not a matchall means the boolean query will not match all } } else { if (willMatchAll(clause.getQuery())) { foundMatchAll = true; } } } //If a matchall has been found, and we haven't return false yet, this boolean query matches all documents return foundMatchAll; } else if (query instanceof DisjunctionMaxQuery) { boolean isMatchAll = false //If any disjunct is a matchall, the query will match all documents for (Query subquery : ((DisjunctuionMaxQuery)query).getDisjuncts()) { isMatchAll = isMatchAll || willMatchAll(subquery); } return isMatchAll; } else if (query instanceof ConstantScoreQuery) { //Traverse right through ConstantScoreQuery. The wrapper isn't of interest here. Query subquery = ((ConstantScoreQuery)query).getQuery() if (subquery == null) { return false; //It wraps a filter, not a query, and I don't believe a filter can be a matchall } return willMatchAll(subquery); } else { //No other standard queries may be or contain MatchAllDocsQueries, I don't believe. //Even a double open-ended range query restricts the results to those with a value in the specified field. return false; } } BoostingQuery等。但希望能给出一些想法。

答案 1 :(得分:0)

好问题,我想知道你是否可以执行搜索并获取numFound并进行比较,看看你的实际Query是否返回相同的numFound值。我错过了什么吗?

相关问题