【问题标题】:Query for nested fields returns results as if there was no nested mapping查询嵌套字段返回结果,就好像没有嵌套映射一样
【发布时间】:2021-07-23 13:32:12
【问题描述】:

我很难理解,为什么跨嵌套字段的查询会返回意外结果。

我的索引有以下模板

PUT /_template/nested_test
{
  "index_patterns": [ "nested-*" ],
  "settings": { "index.mapping.coerce": false },
  "mappings": { 
    "dynamic": "strict",
    "properties" {
      "vNested": {
        "type": "nested",
        "properties": {
           "v1": { "type": "keyword" },
           "v2": {
               "properties": {
                  "v21": {
                    "type": long"
                  }
               }
           }
         }
       }
     } 
  }
}

我会将两个文档发布到与模板匹配的索引中。

POST /nested-example/_doc
{
  "vNested": [
    {
      "v1": "User1",
      "v2": {
        "v21": 1
      }
    },
    {
      "v1": "User3",
      "v2": {
        "v21": 3
      }
    }
  ]
}
POST /nested-example/_doc
{
  "vNested": [
    {
      "v1": "User1",
      "v2": {
        "v21": 3
      }
    },
    {
      "v1": "User2",
      "v2": {
        "v21": 2
      }
    }
  ]
}

现在我将创建一个查询,目标是仅获取那些文档的结果,其中存在 User1 对应的 v21 值为 3。据我了解,我的嵌套映射应该确保我只会得到第二个文档作为查询结果。

以下查询:

GET /nested-example/_search
{
  "query" : {
    "bool": {
      "filter": {
        "bool": {
          "must": [
            {
              "nested: {
                "path": "vNested",
                "query": {
                  "match": {
                    "vNested.v1": "User1"
                  }
                }
              }
            },
            {
              "nested: {
                "path": "vNested",
                "query": {
                  "match": {
                    "vNested.v2.v21": "3"
                  }
                }
              }
            }
          ]
        }
      }
    } 
  }
}

返回两个文档,而不仅仅是我期望的单个文档

我知道查询字符串不是最优雅的 - 这是由于一些业务逻辑 + 前端框架逻辑用于根据用户输入创建查询字符串以及有关如何删除冗余的任何建议欢迎也是。

但是,我很难理解为什么这个查询会返回两个文档,包括 v1=User1 和 v21=1 的 vNested 对象的文档。 vNested 字段的嵌套映射不应该防止这个问题吗?

【问题讨论】:

    标签: elasticsearch nested mapping


    【解决方案1】:

    您需要在nested query 中使用bool/must 查询,因为您查询的是单个对象而不是多个对象。将您的查询修改为

    {
      "query": {
        "bool": {
          "filter": {
            "bool": {
              "must": [
                {
                  "nested": {
                    "path": "vNested",
                    "query": {
                      "bool": {
                        "must": [
                          {
                            "match": {
                              "vNested.v1": "User1"
                            }
                          },
                          {
                            "match": {
                              "vNested.v2.v21": "3"
                            }
                          }
                        ]
                      }
                    },
                    "inner_hits":{}
                  }
                }
              ]
            }
          }
        }
      }
    }
    

    搜索结果是

    "hits": [
          {
            "_index": "nested-example",
            "_type": "_doc",
            "_id": "AAu0IXkBKyWl6Va6kmTU",
            "_score": 0.0,
            "_source": {
              "vNested": [
                {
                  "v1": "User1",
                  "v2": {
                    "v21": 3
                  }
                },
                {
                  "v1": "User2",
                  "v2": {
                    "v21": 2
                  }
                }
              ]
            },
            "inner_hits": {
              "vNested": {
                "hits": {
                  "total": {
                    "value": 1,
                    "relation": "eq"
                  },
                  "max_score": 1.6931472,
                  "hits": [
                    {
                      "_index": "nested-example",
                      "_type": "_doc",
                      "_id": "AAu0IXkBKyWl6Va6kmTU",
                      "_nested": {
                        "field": "vNested",
                        "offset": 0
                      },
                      "_score": 1.6931472,
                      "_source": {
                        "v1": "User1",
                        "v2": {
                          "v21": 3
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        ]
    

    【讨论】:

    • @Mihkel Künnapas 请仔细阅读答案,如果这能解决您的问题,请告诉我?
    • 感谢您的回复,如果能解决我的问题,我会尽快更新。
    • 再次感谢您,我能够检查这确实解决了我的问题。您能否再详细说明一件事,看看我是否正确理解了您的解释。您在回答中说我需要在嵌套查询中添加我的 bool/must 查询,因为我正在查询单个对象。在这种情况下,“单个对象”是否意味着我查询的所有字段都具有相同的嵌套路径?多个对象意味着我有一些单独的嵌套对象(具有不同的嵌套路径),我需要将它们保留为单独的嵌套查询?
    猜你喜欢
    • 2021-09-22
    • 2019-12-20
    • 2019-07-08
    • 2020-10-15
    • 1970-01-01
    • 2018-02-11
    • 2018-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多