查询嵌套字段 returns 结果就像没有嵌套映射一样

Query for nested fields returns results as if there was no nested mapping

我很难理解为什么跨嵌套字段的查询会 return 出乎意料的结果。

我的索引有以下模板

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 两个文档添加到与模板匹配的索引中。

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

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

以下查询:

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

return两个文档,而不是我期望的单个文档

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

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

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

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