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
。现在,如果 IsBundle
是 true
,如果 RelationshipId
与我发送的 searchDto.RelationshipId
匹配,我想要记录。如果IsBundle
是false
,我不关心RelationshipId
。所以我的最终结果将是一些记录组合,其中 IsBundle
是 true
并且 RelationshipId
匹配我的 searchDto.RelationshipId
并且 IsBundle
是 false
如果你把逻辑搞垮,这不就等同于
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 查询,但这满足了要求。
我有一个 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
。现在,如果 IsBundle
是 true
,如果 RelationshipId
与我发送的 searchDto.RelationshipId
匹配,我想要记录。如果IsBundle
是false
,我不关心RelationshipId
。所以我的最终结果将是一些记录组合,其中 IsBundle
是 true
并且 RelationshipId
匹配我的 searchDto.RelationshipId
并且 IsBundle
是 false
如果你把逻辑搞垮,这不就等同于
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 查询,但这满足了要求。