Elasticsearch嵌套组合过滤器问题

时间:2015-03-29 01:15:06

标签: nest elasticsearch-net

我在asp.net mvc应用程序中使用elasticsearch nest。

以下弹性搜索查询会引发异常,因为类别和品牌等字段可能为空或空。如何添加if语句并有条件地构建过滤器。谢谢!

我必须使用bool&必须为搜索条件组合(AND)过滤器。例如,用户想要“鞋子”类别和零售商“macys”中的产品。

 s.Query(q => q
                .Bool(bq => bq
                    .Must(
                        mq => mq.Filtered(fq => fq
                            .Filter(f => f.Terms("Categories", request.Categories))
                            ),
                        mq => mq.Filtered(fq => fq
                            .Filter(f => f.Terms("BrandName", request.Brands))
                            ),
                        mq => mq.Filtered(fq => fq
                            .Filter(f => f.Terms("RetailerName", request.Retailers))
                            ),
                        mq => mq.Filtered(fq => fq
                            .Filter(f => f.Terms("RetailerName", request.Retailers))
                            ),
                        mq => mq.Range(r => r
                            .OnField("SellingPrice")
                            .GreaterOrEquals((double)request.PriceRanges[0].Start)
                            .LowerOrEquals((double)request.PriceRanges[0].End)
                            )
                    )
                )
             );    

1 个答案:

答案 0 :(得分:0)

您不必关心传递给查询的空值或空值,因为NEST具有名为Conditionless Queries的功能。文档说

  

如果任何查询导致空查询,他们将不会   发送给Elasticsearch。

异常的原因是这些代码行:

mq => mq.Range(r => r
    .OnField("SellingPrice")
    .GreaterOrEquals((double)request.PriceRanges[0].Start)
    .LowerOrEquals((double)request.PriceRanges[0].End)
)

可行PriceRanges为空或空,您尝试从第一个元素访问StartEnd属性。如果您能够将请求类更改为下面的内容,如果您只使用PriceRanges中的第一项,那就太棒了:

class Request
{
    public List<string> Categories { get; set; }
    public List<string> Brands { get; set; }
    public double? PriceRangeStart { get; set; }
    public double? PriceRangeEnd { get; set; }
}

然后您的NEST查询将如下所示:

s.Query(q => q
    .Bool(bq => bq
        .Must(
            mq => mq.Filtered(fq => fq
                .Filter(f => f.Terms("Categories", request.Categories))
                ),
            mq => mq.Filtered(fq => fq
                .Filter(f => f.Terms("BrandName", request.Brands))
                ),
            mq => mq.Filtered(fq => fq
                .Filter(f => f.Terms("RetailerName", request.Retailers))
                ),
            mq => mq.Range(r => r
                .OnField("SellingPrice")
                .GreaterOrEquals(request.PriceRangeStart)
                .LowerOrEquals(request.PriceRangeEnd)
                )
        )
    ));

对于此请求对象

var request = new Request
{
    Brands = new List<string>{"brand"},
    PriceRangesEnd = 100
};

NEST生成以下弹性搜索查询

"query": {
  "bool": {
    "must": [
      {
        "filtered": {
          "filter": {
            "terms": {
              "BrandName": [
                "brand"
              ]
            }
          }
        }
      },
      {
        "range": {
          "SellingPrice": {
            "lte": "100"
          }
        }
      }
    ]
  }
}