我想用NEST添加多个bool过滤器,但我不能(实际上)在一个语句中执行它,因为我想构建一组 Bool 过滤器,具体取决于不同的条件
像这样的伪代码:
// Append a filter
searchDescriptor.Filter(f => f.Bool(b => b.Must(m => m.Term(i => i.SomeProperty, "SomeValue"))));
if (UserId.HasValue)
{
// Optionally append another filter (AND condition with the first filter)
searchDescriptor.Filter(f => f.Bool(b => b.Must(m => m.Term(i => i.AnotherProperty, "MyOtherValue"))));
}
var result = Client.Search(searchDescriptor);
现在看来,当附加第二个可选过滤器时,它基本上取代了第一个过滤器。
我确定我在语法上遗漏了一些东西,但是我无法理解它并且过滤器DSL上的NEST文档有点薄。 :)
答案 0 :(得分:12)
关于编写查询的部分也非常适用于过滤器: http://nest.azurewebsites.net/nest/writing-queries.html
您最终得到的解决方案不太理想,因为您将bool
过滤器包装在具有非常不同的缓存机制的and
过滤器内(并且过滤器不使用缓存的位集,因此在大多数情况下案件表现比常规bool过滤器差。)
强烈建议您阅读http://www.elasticsearch.org/blog/all-about-elasticsearch-filter-bitsets/,因为它很好地解释了和/或/不是过滤器与bool过滤器之间的区别。
你可以这样重写:
Client.Search(s=>s
.Filter(f=> {
BaseFilter ff = f.Term(i => i.MyProperty, "SomeValue");
if (UserId.HasValue)
ff &= f.Term(i => i.AnotherProperty, "AnotherValue");
return ff;
})
);
如果第二个术语是使用UserId进行搜索,您可以利用NEST的conditionless queries
Client.Search(s=>s
.Filter(f=>
f.Term(i => i.MyProperty, "SomeValue")
&& f.Term(i => i.AnotherProperty, UserId)
)
);
如果UserId
为null,那么术语查询将不会作为查询的一部分生成,在这种情况下,nest甚至不会将单个剩余项包装在bool过滤器中,而只是将其作为普通过程发送术语过滤器。
答案 1 :(得分:1)
啊,这样的事情似乎有效:
var filters = new List<BaseFilter>();
// Required filter
filters.Add(new FilterDescriptor<MyType>().Bool(b => b.Must(m => m.Term(i => i.MyProperty, "SomeValue"))));
if (UserId.HasValue)
{
filters.Add(new FilterDescriptor<MyType>().Bool(b => b.Must(m => m.Term(i => i.AnotherProperty, "AnotherValue"))));
}
// Filter with AND operator
searchDescriptor.Filter(f => f.And(filters.ToArray()));
var result = Client.Search(searchDescriptor);