繁体   English   中英

Lucene.Net 查询有两个 MUST 子句返回不正确的结果

[英]Lucene.Net Query with two MUST Clauses Returning Incorrect Results

我创建了一个带有两个 MUST 子句(和零个 SHOULD 子句)的查询,该查询返回的结果只满足其中一个子句。 据我所知,这是不正确的行为。

搜索前此类查询的一个示例是

{+(Text:wba) +(Attribute:10)}

返回的错误结果在“文本”字段中将“wba”作为术语,但在“属性”字段中没有将“10”作为术语。

当我查看我在 Luke 中的索引时,转到“搜索”选项卡,然后运行此搜索

+Text:wba +Attribute:10

正如我所料,我没有得到任何结果。

这是运行搜索的代码的稍微简化版本:

public static ScoreDoc[] Search( string searchPhrase, int maxResults, IEnumerable<string> attributes ) {

    var topQuery = new BooleanQuery();

    var textQuery = new BooleanQuery();
    using( var ngAnalyzer = new NGramAnalyzer( Version.LUCENE_30, 3, 9 ) ) {
        using( var stAnalyzer = new StandardAnalyzer( Version.LUCENE_30, new HashSet<string>() ) ) {

            var ngParser = new QueryParser( Version.LUCENE_30, IndexManager.TextFieldName, ngAnalyzer );
            var stParser = new QueryParser( Version.LUCENE_30, IndexManager.TextFieldName, stAnalyzer );

            var terms = AutoCompleter.QueryToTerms( searchPhrase );

            foreach( var word in terms ) {
                if( string.IsNullOrWhiteSpace( word ) ) {
                    continue;
                }

                if( word.Length < 3 ) {
                    textQuery.Add( stParser.Parse( word ), Occur.MUST );
                } else {
                    var parsed = ngParser.Parse( word );

                    var extractedTerms = new HashSet<Term>();
                    parsed.ExtractTerms( extractedTerms );
                    foreach( var term in extractedTerms ) {
                        textQuery.Add( new TermQuery( term ), Occur.SHOULD );
                    }
                }
            }
        }
    }
    topQuery.Add( textQuery, Occur.MUST );

    if( attributes != null && attributes.Any() ) {
        var attrQuery = new BooleanQuery();
        foreach( var attr in attributes ) {
            attrQuery.Add( new TermQuery( new Term( IndexManager.AttributeFieldName, attr ) ), Occur.SHOULD );
        }
        topQuery.Add( attrQuery, Occur.MUST );
    }

    // Actually conduct the search
    var searcher = AutoCompleter.IndexManager.GetOrCreateSearcher( AutoCompleter.TableId );

    var resultDocs = searcher.Search( textQuery, maxResults ).ScoreDocs;

    return resultDocs;
}

以下是生成索引的代码的摘录:

// Add the new document
var doc = new Document();
var field = new Field( IndexManager.TextFieldName, term.Text, Field.Store.YES, Field.Index.ANALYZED );
doc.Add( field );
if( !String.IsNullOrWhiteSpace( term.Id ) ) {
    field = new Field( IndexManager.IdFieldName, term.Id, Field.Store.YES, Field.Index.NO );
    doc.Add( field );
}
foreach( var attr in term.Attributes ) {
    if( !String.IsNullOrWhiteSpace( attr ) ) {
        field = new Field( IndexManager.AttributeFieldName, attr, Field.Store.YES, Field.Index.NOT_ANALYZED );
        doc.Add( field );
    }
}
writer.AddDocument( doc );

因此,要清楚,我只希望匹配中的文本条款的结果textQuery并在召开的属性条款的至少一个attrQuery 为什么这不像我期望的那样工作?

这一行是错误的:

var resultDocs = searcher.Search( textQuery, maxResults ).ScoreDocs;

应该:

var resultDocs = searcher.Search( topQuery, maxResults ).ScoreDocs;

哎呀。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM