如何过滤应查询的嵌套对象? [英] How to filter nested objects on a should query?

查看:43
本文介绍了如何过滤应查询的嵌套对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的映射如下,并且我正在做布尔查询名称和其他属性,如下所示,但是我需要的是我想在响应时按CustomerId过滤CustomerPrices.每个产品都有相同的CustomerId,因此适用于eampample;

I have my mappings as below and I am doing a bool should query on name and other properties as shown below but what I need is that I want to filter CustomerPrices by CustomerId on response. Each products have same CustomerIds so for eaxample;

product1 -CustomerPrice( CustomerId :1234 -Price:4) 
           CustomerPrice( CustomerId :567-Price:5)
            .
            .
 Product2 - CustomerPrice(CustomerId :1234 -Price:8)
            CustomerPrice(CustomerId :567-Price:10)
           .
           .

因此,据此,当我查询Product1时,响应中应仅将customerId用作customerId:1234

So according to that when I query Product1, response should have only customerPrice for customerId:1234

{
  "Product": {
    "properties": {
      "CustomerPrices": {
        "type": "nested",
        "properties": {
          "Price": {
            "store": true,
            "type": "float"
          },
          "CustomerId": {
            "type": "integer"
          }
        }
      },
      "Name": {
        "index": "not_analyzed",
        "store": true,
        "type": "string"
      }
    }
  }
}

我尝试了以下查询,但这并未过滤嵌套对象.我猜它会过滤产品对象,因为所有产品都有customerId:1234

I tried following query but this is not filtering nested objects. I guess it filters product objects as it makes sense because all products have customerId:1234

   "query":{
        "bool":{
          "should":[
            {
              "multi_match":{
                "type":"best_fields",
                "query":"product 1",
                "fields":[             
                  "Name^7"]
              }
            },
            {
              "multi_match":{
                "type":"best_fields",
                "query":"product 1",
                "operator":"and",
                "fields":[
                  "Code^10",           
                  "ShortDescription^6"]
              }
            },      
            {
              "nested":{
                "query":{
                  "term":{
                    "CustomerPrices.CustomerId":{
                      "value":1234
                    }
                  }
                },
                "path":"CustomerPrices"
              }
            }]
        }
      },

推荐答案

我花了一些时间解决您的问题,因为这很有趣,而且我目前发现的唯一解决方案是依靠inner_hits ,它给出了匹配所在的确切嵌套对象.我还停用了不再使用的 _source .

I've spent some time on your question since it was interesting how this can be achieved and the only solution I found for now is relying on the inner_hits which gives the exact nested object the match was on. I've also deactivated the _source which isn't used anymore.

因此,根据您的映射,您有2种产品,例如:

So given your mapping and having 2 products like:

PUT product/Product/product1
{
  "CustomerPrices": [
    {
      "CustomerId": 1234,
      "Price": 4
    },
    {
      "CustomerId": 567,
      "Price": 5
    }
  ],
  "Name": "John"
}

PUT product/Product/product2
{
  "CustomerPrices": [
    {
      "CustomerId": 1234,
      "Price": 8
    },
    {
      "CustomerId": 567,
      "Price": 10
    }
  ],
  "Name": "Bob"
}

运行以下查询时:(使用必须只是为了查看1个结果,还应与 should 一起使用")

When running the following query: (Used must just to see 1 result, works with should as well)

GET product/_search
{
  "_source": false,
  "query": {
    "bool": {
      "must": [
        { "match": { "Name": "Bob"}}
      ],
      "filter": [
        {
          "nested" : {
            "path" : "CustomerPrices",
            "score_mode" : "avg",
            "query" : {
              "bool" : {
                "should" : [
                  { "match" : {"CustomerPrices.CustomerId" : 1234}}
                ]
              }
            },
            "inner_hits": {}
          }
        }
      ]
    }
  }
}

我能够得到结果,其中只显示ID为1234的客户的价格":

I was able to get the result where only "Price" from customer with id 1234 was present:

{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "product",
        "_type": "Product",
        "_id": "product2",
        "_score": 0.2876821,
        "inner_hits": {
          "CustomerPrices": {
            "hits": {
              "total": 1,
              "max_score": 1,
              "hits": [
                {
                  "_index": "product",
                  "_type": "Product",
                  "_id": "product2",
                  "_nested": {
                    "field": "CustomerPrices",
                    "offset": 0
                  },
                  "_score": 1,
                  "_source": {
                    "CustomerId": 1234,
                    "Price": 8
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}

仅通过具有匹配的嵌套对象,无法找到返回文档部分结果的正式方法.也许我们需要告知Elasticsearch的人员有关一些后续版本的考虑.希望对您有帮助.

Couldn't find an official way of returning partial results of the document by only having the matched nested object. Maybe something that we need to inform elasticsearch guys about to consider for some next releases. Hope it helps you.

这篇关于如何过滤应查询的嵌套对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆