确定Lucene BooleanQuery中哪个参数失败?

时间:2014-04-03 18:03:56

标签: java lucene

如果整个查询没有返回任何结果,我需要确定Lucene BooleanQuery的哪个部分失败。

我正在使用由BooleanQueryNumericRangeQueries组成的PhraseQuery。每个都添加到Occur.MUST的查询中。

如果我没有得到查询的任何结果,有没有办法告诉查询的哪个部分无法匹配任何内容?我是否需要单独运行查询并比较结果才能获得失败的查询?

修改 - 添加了PhraseQuery代码。

if( row.getPropertykey_tx() != null && !row.getPropertykey_tx().trim().isEmpty()){
    PhraseQuery pQuery = new PhraseQuery();
    String[] words = row.getPropertykey_tx().trim().split(" ");
    for( String word : words ){
        pQuery.add(new Term(TitleRecordColumns.SA_SITE_ADDR.toString(), word));
    }
    pQuery.setSlop(2);

    topBQuery.add(pQuery, BooleanClause.Occur.MUST);
}

1 个答案:

答案 0 :(得分:1)

在我看来,运行查询的各个部分可能是最简单的方法。

另一个可用的工具是获得Explaination。您可以调用IndexSearcher.explain来获取针对特定文档的查询评分的说明。如果您可以提供您认为应与查询匹配的文档的docid,则可以分析Explanation.toString(或toHtml,如果您愿意)以确定哪些子查询不匹配。


如果你想自动记录一个BooleanQuery的哪个子句没有产生结果,我相信你需要独立运行每个查询。如果您无法再访问用于创建它的子查询,则可以改为使用它的子句:

findTroublesomeQuery(BooleanQuery query) {
    for (BooleanClause clause : query.clauses()) {
        Query subquery = clause.getQuery()
        TopDocs docs = searchHoweverYouDo(subquery);
        if  (doc.totalSize == 0) {
            //If you want to dig down recursively...
            if (subquery instanceof BooleanQuery)
                findTroublesomeQuery(query);
            else 
                log(query); //Or do whatever you want to keep track of it.
        }
    }
}

DisjunctionMaxQuery是一个常用的查询,它也包含多个子查询,因此对于这种方法可能值得考虑。