【问题标题】:How to fetch only specific object inside nested field along with search query in Elasticsearch如何在 Elasticsearch 中仅获取嵌套字段中的特定对象以及搜索查询
【发布时间】:2021-03-11 08:50:00
【问题描述】:

我有一个包含嵌套字段的索引。我想根据条件以及其他字段仅包含特定的嵌套对象作为响应。例如考虑映射

    PUT /users
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "address": {
        "type": "nested",
        "properties": {
          "state": {
            "type": "keyword"
          },
          "city": {
            "type": "keyword"
          },
          "country": {
            "type": "keyword"
          }
        }
      }
    }
  }

我想按名称搜索用户,并期望响应只包含嵌套对象 contains country = 'United States"。考虑用户索引中的以下文档

 {
        "users": [
            {
                "name": "John",
                "address": [
                    {
                        "state": "Alabama",
                        "city": "Alabaster",
                        "Country": "United States"
                    },
                    {
                        "state": "New Delhi",
                        "city": "Agra",
                        "Country": "India"
                    }
                ]
            },
            {
                "name": "Edward John",
                "address": [
                    {
                        "state": "Illinois",
                        "city": "Chicago",
                        "Country": "United States"
                    },
                    {
                        "state": "Afula",
                        "city": "Afula",
                        "Country": "Israel"
                    }
                ]
            },
,
            {
                "name": "Edward John",
                "address": [
                    {
                        "state": "Afula",
                        "city": "Afula",
                        "Country": "Israel"
                    }
                ]
            }
        ]
    }

我期待的搜索结果如下

  {
        "users": [
            {
                "name": "John",
                "address": [
                    {
                        "state": "Alabama",
                        "city": "Alabaster",
                        "Country": "United States"
                    }
                ]
            },
            {
                "name": "Edward John",
                "address": [
                    {
                        "state": "Illinois",
                        "city": "Chicago",
                        "Country": "United States"
                    }
                ]
            },
,
            {
                "name": "Edward John",
                "address": [
                ]
            }
        ]
    }

请为我提供一个合适的 elasticsearch 查询来获取此文档

【问题讨论】:

    标签: elasticsearch spring-data-elasticsearch


    【解决方案1】:

    正确的查询应该是这个:

    POST users/_search
    {
      "_source": [
        "name"
      ],
      "query": {
        "bool": {
          "should": [
            {
              "nested": {
                "path": "address",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "match": {
                          "address.Country": "United States"
                        }
                      }
                    ]
                  }
                },
                "inner_hits": {}
              }
            },
            {
              "bool": {
                "must_not": [
                  {
                    "nested": {
                      "path": "address",
                      "query": {
                        "bool": {
                          "must": [
                            {
                              "match": {
                                "address.Country": "United States"
                              }
                            }
                          ]
                        }
                      }
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
    

    返回这个:

      "hits" : {
        "total" : {
          "value" : 3,
          "relation" : "eq"
        },
        "max_score" : 1.489748,
        "hits" : [
          {
            "_index" : "users",
            "_type" : "_doc",
            "_id" : "X8pINHgB2VNT6r1rJj04",
            "_score" : 1.489748,
            "_source" : {
              "name" : "John"
            },
            "inner_hits" : {
              "address" : {
                "hits" : {
                  "total" : {
                    "value" : 1,
                    "relation" : "eq"
                  },
                  "max_score" : 1.489748,
                  "hits" : [
                    {
                      "_index" : "users",
                      "_type" : "_doc",
                      "_id" : "X8pINHgB2VNT6r1rJj04",
                      "_nested" : {
                        "field" : "address",
                        "offset" : 0
                      },
                      "_score" : 1.489748,
                      "_source" : {
                        "city" : "Alabaster",
                        "Country" : "United States",
                        "state" : "Alabama"
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            "_index" : "users",
            "_type" : "_doc",
            "_id" : "XftINHgBAEsNDPLQQxL8",
            "_score" : 1.489748,
            "_source" : {
              "name" : "Edward John"
            },
            "inner_hits" : {
              "address" : {
                "hits" : {
                  "total" : {
                    "value" : 1,
                    "relation" : "eq"
                  },
                  "max_score" : 1.489748,
                  "hits" : [
                    {
                      "_index" : "users",
                      "_type" : "_doc",
                      "_id" : "XftINHgBAEsNDPLQQxL8",
                      "_nested" : {
                        "field" : "address",
                        "offset" : 0
                      },
                      "_score" : 1.489748,
                      "_source" : {
                        "city" : "Chicago",
                        "Country" : "United States",
                        "state" : "Illinois"
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            "_index" : "users",
            "_type" : "_doc",
            "_id" : "UoZINHgBNlJvCnAGVzE9",
            "_score" : 0.0,
            "_source" : {
              "name" : "Edward John"
            },
            "inner_hits" : {
              "address" : {
                "hits" : {
                  "total" : {
                    "value" : 0,
                    "relation" : "eq"
                  },
                  "max_score" : null,
                  "hits" : [ ]
                }
              }
            }
          }
        ]
      }
    

    【讨论】:

      【解决方案2】:

      试试下面的查询

       {
            "query": {
              "nested": {
                "path": "address",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "match": {
                          "address.Country": "United States"
                        }
                      }
                    ]
                  }
                },
                "inner_hits": {}
              }
            }
          }
      

      搜索结果将是

      "hits": [
            {
              "_index": "66579117",
              "_type": "_doc",
              "_id": "1",
              "_score": 0.6931471,
              "_source": {
                "name": "John",
                "address": [
                  {
                    "sate": "Alabama",
                    "city": "Alabaster",
                    "Country": "United States"
                  },
                  {
                    "sate": "New Delhi",
                    "city": "Agra",
                    "Country": "India"
                  }
                ]
              },
              "inner_hits": {
                "address": {
                  "hits": {
                    "total": {
                      "value": 1,
                      "relation": "eq"
                    },
                    "max_score": 0.6931471,
                    "hits": [
                      {
                        "_index": "66579117",
                        "_type": "_doc",
                        "_id": "1",
                        "_nested": {
                          "field": "address",
                          "offset": 0
                        },
                        "_score": 0.6931471,
                        "_source": {
                          "sate": "Alabama",
                          "city": "Alabaster",
                          "Country": "United States"
                        }
                      }
                    ]
                  }
                }
              }
            },
            {
              "_index": "66579117",
              "_type": "_doc",
              "_id": "2",
              "_score": 0.6931471,
              "_source": {
                "name": "Edward",
                "address": [
                  {
                    "sate": "Illinois",
                    "city": "Chicago",
                    "Country": "United States"
                  },
                  {
                    "sate": "Afula",
                    "city": "Afula",
                    "Country": "Israel"
                  }
                ]
              },
              "inner_hits": {
                "address": {
                  "hits": {
                    "total": {
                      "value": 1,
                      "relation": "eq"
                    },
                    "max_score": 0.6931471,
                    "hits": [
                      {
                        "_index": "66579117",
                        "_type": "_doc",
                        "_id": "2",
                        "_nested": {
                          "field": "address",
                          "offset": 0
                        },
                        "_score": 0.6931471,
                        "_source": {
                          "sate": "Illinois",
                          "city": "Chicago",
                          "Country": "United States"
                        }
                      }
                    ]
                  }
                }
              }
            }
          ]
      

      【讨论】:

      • 好的。此嵌套查询仅返回包含 address.country = "United States" 的用户。但是索引中还有其他名称包含“John”的文件,这些文件的地址在其他国家/地区。这些文件不会被退回。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 2020-07-23
      相关资源
      最近更新 更多