0

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

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

我必须使用 bool & must 来组合(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)
                            )
                    )
                )
             );    
4

1 回答 1

0

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

如果任何查询会导致空查询,它们将不会被发送到 Elasticsearch。

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

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

可能PriceRanges是 null 或空,并且您正在尝试从第一个元素访问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"
          }
        }
      }
    ]
  }
}
于 2015-03-29T15:46:01.057 回答