如何过滤应该查询的嵌套对象?

时间:2018-02-12 16:08:36

标签: elasticsearch

我的映射如下,我正在做一个bool应该查询名称和其他属性,如下所示,但我需要的是我想要在CustomerId上响应CustomerPrices。 每个产品都有相同的CustomerIds,因此对于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的customerPrice: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

   "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"
              }
            }]
        }
      },

1 个答案:

答案 0 :(得分:2)

我花了一些时间在你的问题上,因为有趣的是如何实现这一点,我现在找到的唯一解决方案是依靠 inner_hits ,它给出了匹配的确切嵌套对象上。我还停用了 _source ,它已不再使用了。

所以给出你的映射并有两个产品,如:

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个结果,与一起使用也是如此)

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的客户的“价格”存在:

{
  "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的人要考虑下一个版本。希望它可以帮到你。