ElasticSearch - 嵌套查询返回的数据过滤

问题描述 投票:0回答:1

我有一组数据,结构如下。

[
    {
        "productId": "ProductId1",
        "customerNumbers": [
            "customer": {
                "name": "Prod1Cust1",
                "totalOrders": 23
            },
            "customer": {
                "name": "Prod2Cust1",
                "totalOrders": 5
            },
            "customer": {
                "name": "Prod3Cust1",
                "totalOrders": 5
            }
        ]
    },
    {
        "productId": "ProductId2",
        "customerNumbers": [
            "customer": {
                "name": "Prod2Cust1",
                "totalOrders": 23
            },
            "customer": {
                "name": "Prod2Cust1",
                "totalOrders": 5
            }
        ]
    }
]

我需要获取所有的记录,其中有一个... 前缀 的 "Prod1如 名称 字段(在本例中,只需要返回第一条记录,即ProductId1)。另外,当数据被返回时,我需要只获取前缀为Prod1的客户号,即

正确的输出:

{
        "productId": "ProductId1",
        "customerNumbers": [
            "customer": {
                "name": "Prod1Cust1",
                "totalOrders": 23
            }
        ]
    }

正确的输出是:

{
        "productId": "ProductId1",
        "customerNumbers": [
            "customer": {
                "name": "Prod1Cust1",
                "totalOrders": 23
            },
            "customer": {
                "name": "Prod2Cust1",
                "totalOrders": 5
            },
            "customer": {
                "name": "Prod3Cust1",
                "totalOrders": 5
            }
        ]
    }

我可以获取前缀是Prod1的客户号的记录 名称 前缀是 "Prod1",使用嵌套查询加上MatchPhrasePrefixQuery(这将返回我所有客户号码的结果)。我如何进一步过滤数据,以获得客户号码,其 名称 前缀是 "Prod1"。

以下是我当前的查询。

{
    "from": 0,
    "size": 10,
    "sort": [
        {
            "name.keyword": {
                "missing": "_first",
                "order": "asc"
            }
        }
    ],
    "query": {
        "bool": {
            "must": [
                {
                    "bool": {
                        "must": [
                            {
                                "nested": {
                                    "query": {
                                        "bool": {
                                            "must": [
                                                {
                                                    "match": {
                                                        "customerNumbers.name": {
                                                            "query": "Prod1",
                                                            "type": "phrase_prefix"
                                                        }
                                                    }
                                                }
                                            ]
                                        }
                                    },
                                    "path": "customerNumbers"
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}

P.S: 我使用ElasticSearch 5.x和Nest.

elasticsearch nest
1个回答
1
投票

尝试使用 inner_hits:

PUT products
{"mappings":{"_doc":{"properties":{"customerNumbers":{"type":"nested"}}}}}

POST products/_doc
{"productId":"ProductId1","customerNumbers":[{"name":"Prod1Cust1","totalOrders":23},{"name":"Prod2Cust1","totalOrders":5},{"name":"Prod3Cust1","totalOrders":5}]}

POST products/_doc
{"productId":"ProductId2","customerNumbers":[{"name":"Prod2Cust1","totalOrders":23},{"name":"Prod2Cust1","totalOrders":5}]}
GET products/_search
{
  "_source": "inner_hits", 
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "must": [
              {
                "nested": {
                  "path": "customerNumbers",
                  "query": {
                    "bool": {
                      "must": [
                        {
                          "match_phrase_prefix": {
                            "customerNumbers.name": {
                              "query": "Prod1"
                            }
                          }
                        }
                      ]
                    }
                  },
                  "inner_hits": {}
                }

              }
            ]
          }
        }
      ]
    }
  }
}

产生以下点击率

[
  {
    "_index":"products",
    "_type":"_doc",
    "_id":"tyQGo3EBdiyDG0RsTa0N",
    "_score":0.9808292,
    "_source":{

    },
    "inner_hits":{
      "customerNumbers":{
        "hits":{
          "total":1,
          "max_score":0.9808292,
          "hits":[
            {
              "_index":"products",
              "_type":"_doc",
              "_id":"tyQGo3EBdiyDG0RsTa0N",
              "_nested":{
                "field":"customerNumbers",
                "offset":0
              },
              "_score":0.9808292,
              "_source":{
                "name":"Prod1Cust1",         <-----
                "totalOrders":23
              }
            }
          ]
        }
      }
    }
  }
]
© www.soinside.com 2019 - 2024. All rights reserved.