【问题标题】:Elasticsearch nest combination filter issueElasticsearch 嵌套组合过滤器问题
【发布时间】:2015-03-29 01:15:05
【问题描述】:

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

【问题讨论】:

    标签: nest elasticsearch-net


    【解决方案1】:

    您不必关心传递给查询的 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"
              }
            }
          }
        ]
      }
    }
    

    【讨论】:

    • 谢谢! f.Terms("Categories", request.Categories) 比较任何类别。我如何比较所有?例如“鞋子”、“礼物”。我想要返回类别匹配“鞋子”和“礼物”(不是“鞋子”或“礼物”)的结果。我确实看到了条款过滤器的执行选项,我不知道这是否有帮助。
    • 您可以分享您的索引映射吗?
    • mq =&gt; mq.Filtered(fq =&gt; fq .Filter(f =&gt; f.Terms("Categories", request.Categories,TermsExecution.And)) 比较所有内容,但区分大小写。我在映射中有这个字段 not_analyzed。如何使比较不区分大小写?这是字段 "Categories" : { "type" : "string", "index_name" : "Category", "index" : "not_analyzed" } 的映射
    • 这是完整的映射。我正在使用类别和其他几个字段进行聚合。 -d '{"settings" : {"number_of_shards" : 1 }, "mappings" : {"summary" : { "properties" : {"RetailerName" : { "type" : "string", "index" : "not_analyzed" }, "BrandName" : { "type" : "string", "index" : "not_analyzed" }, "SellingPrice" : { "type" : "float" }, "AffiliateMarketingVerbs" : { "type" : "string", "index_name" : "AffiliateMarketingVerb", "index" : "not_analyzed" }, "Categories" : { "type" : "string", "index_name" : "Category", "index" : "not_analyzed" } } } } }'
    猜你喜欢
    • 2021-04-19
    • 2020-12-02
    • 2018-01-30
    • 2014-12-31
    • 2017-07-27
    • 2015-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多