【问题标题】:Appending multiple bool filters to a NEST query将多个布尔过滤器附加到 NEST 查询
【发布时间】:2021-04-24 19:28:37
【问题描述】:

我想用 NEST 附加多个布尔过滤器,但我不能(实际上)在单个语句中完成,因为我想根据不同的条件构建一组 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);

现在看来,当附加第二个可选过滤器时,它实际上取代了第一个过滤器。

我确定我在语法上遗漏了一些东西,但我无法弄清楚,而且 NEST 文档在过滤器 DSL 上有点薄。 :)

【问题讨论】:

    标签: elasticsearch nest


    【解决方案1】:

    关于编写查询的部分也几乎适用于过滤器: https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/writing-queries.html

    您最终得到的解决方案不太理想,因为您将 bool 过滤器包装在 and 过滤器中,该过滤器具有非常不同的缓存机制(并且过滤器不使用缓存的位集,因此在大多数情况下性能更差常规布尔过滤器)。

    强烈推荐阅读http://www.elastic.co/blog/all-about-elasticsearch-filter-bitsets/,因为它很好地解释了和/或/非过滤器与布尔过滤器之间的区别。

    你实际上可以这样重写:

    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 为空,则不会生成术语查询作为查询的一部分,在这种情况下,嵌套甚至不会将单个剩余术语包装在布尔过滤器中,而是将其作为普通术语过滤器发送而是。

    【讨论】:

      【解决方案2】:

      啊,这样的事情似乎有效:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多