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

时间:2017-01-18 11:42:04

标签: search lucene lucene.net

我有一个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。因此,我的最终结果将是IsBundletrueRelationshipIdsearchDto.RelationshipId匹配且IsBundlefalse的记录组合

2 个答案:

答案 0 :(得分:2)

如果你崩溃逻辑,这不等于

storeInOrder(root1,arr1,0);

private static void storeInOrder(Node root1, int[] arr1, int index) {       
    if(root1 == null){return;}

    storeInOrder(root1.left, arr1,index);       
    arr1[index++] = root1.data;
    storeInOrder(root1.right,arr1,index);
}

IsBundle==false OR RelationshipID==x

答案 1 :(得分:1)

如果没有关于索引字段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)
        );
}

可能有一种优雅的方式来组装查询,但这符合要求。