Lucene.net 过滤索引记录是否有特定值

Lucene.net filter if index record has specific value

我有一个 Lucene.net 索引,其中包含应用多个查询的搜索:

BooleanQuery filterQuery = new BooleanQuery();

if (searchDto.SubCategoryId != Guid.Empty)
{
    TermQuery tq = new TermQuery(new Term("SubCategoryId", searchDto.SubCategoryId.ToString()));
    filterQuery.Add(tq, Occur.MUST);
}

if (!string.IsNullOrEmpty(searchDto.SearchPhrase))
{
    var parser = new MultiFieldQueryParser
      (Version.LUCENE_30, new[] { "Title", "Description", "SubCategoryName", "LongDescription" }, analyzer);
    var query = parseQuery(searchDto.SearchPhrase, parser);
    filterQuery.Add(query, Occur.MUST);
}

topDocs = searcher.Search(filterQuery, null, hits_limit);

效果很好。例如,如果我向它传递一个子类别 ID,它只会匹配一个子类别。但是,我如何制定一个匹配的查询,而不是基于我是否向它发送过滤值,而是基于索引记录是否具有其中一个字段的值。

例如,lucene 索引记录字段之一是 IsBundle。现在,如果 IsBundletrue,如果 RelationshipId 与我发送的 searchDto.RelationshipId 匹配,我想要记录。如果IsBundlefalse,我不关心RelationshipId。所以我的最终结果将是一些记录组合,其中 IsBundletrue 并且 RelationshipId 匹配我的 searchDto.RelationshipId 并且 IsBundlefalse

如果你把逻辑搞垮,这不就等同于

IsBundle==false OR RelationshipID==x

var q = new BooleanQuery();
q.Add(new TermQuery(new Term("IsBundle", "true"), Occur.SHOULD);
q.Add(new TermQuery(new Term("RelationshipID", dto.thing), Ocurr.SHOULD);

没有关于索引字段 RelationshipID 的细节,我假设 RelationshipID 是字符串类型。

如果searchDto.RelationshipID是你想要的

(RelationshipID:{searchDto.RelationshipID} AND IsBundle:true) OR IsBundle:false

如果没有给出searchDto.RelationshipID

IsBundle:false

此代码将适当的查询添加到 filterQuery。

if (!String.IsNullOrEmpty(searchDto.RelationshipID))
{
    BooleanQuery q = new BooleanQuery();
    q.Add(new BooleanClause(
        new TermQuery(new Term("RelationshipId", searchDto.RelationshipID)), Occur.MUST)
        );
    q.Add(new BooleanClause(
        new TermQuery(new Term("IsBundle", "true")), Occur.MUST)
        );
    BooleanClause clause = new BooleanClause(q, Occur.SHOULD);
    q = new BooleanQuery();
    q.Add(clause);
    q.Add(new BooleanClause(
                        new TermQuery(new Term("IsBundle", "false")), Occur.SHOULD)
                        );                
    filterQuery.Add(q,Occur.MUST);            
}
else
{
    filterQuery.Add(new BooleanClause(
        new TermQuery(new Term("IsBundle", "false")), Occur.MUST)
        );
}

可能有一种优雅的方式来 assemble 查询,但这满足了要求。