将多个bool过滤器附加到NEST查询

时间:2013-10-28 16:48:08

标签: elasticsearch nest

我想用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文档有点薄。 :)

2 个答案:

答案 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);