原英文版地址: https://www.elastic.co/guide/en/elasticsearch/reference/7.7/query-dsl-nested-query.html, 原文档版权归 www.elastic.co 所有
本地英文版地址: ../en/query-dsl-nested-query.html

嵌套(nested)查询

包裹另一个查询以搜索nested(嵌套)字段。

nested查询搜索嵌套的字段对象,就好像它们被索引为单独的文档一样。 如果对象与搜索匹配,nested查询将返回根父文档。

请求示例

准备一个索引

若要使用nested查询,索引必须包含nested字段映射。例如:

PUT /my_index
{
    "mappings" : {
        "properties" : {
            "obj1" : {
                "type" : "nested"
            }
        }
    }
}

查询示例

GET /my_index/_search
{
    "query":  {
        "nested" : {
            "path" : "obj1",
            "query" : {
                "bool" : {
                    "must" : [
                    { "match" : {"obj1.name" : "blue"} },
                    { "range" : {"obj1.count" : {"gt" : 5}} }
                    ]
                }
            },
            "score_mode" : "avg"
        }
    }
}

nested的顶级参数

path
(必需, string) 要搜索的嵌套对象的路径。
query

(必需, query object) 要在指定的path中的嵌套对象上运行的查询。 如果一个对象与搜索匹配,nested查询将返回根父文档。

可以使用包含完整路径的点符号来搜索嵌套字段,例如obj1.name

自动支持和检测多级嵌套,导致内部嵌套查询自动匹配相关的嵌套层级,而不是根(如果它存在于另一个嵌套查询中)。-- TODO 待根据后面的内容修正 Multi-level nesting is automatically supported, and detected, resulting in an inner nested query to automatically match the relevant nesting level, rather than root, if it exists within another nested query.

有关示例请参考 多级嵌套查询

score_mode

(可选, string) 指示匹配子对象的分数如何影响根父文档的相关性评分。有效值有:

avg (默认)
使用所有匹配子对象的相关性评分的平均分。
max
使用所有匹配子对象的相关性评分的最高分。
min
使用所有匹配子对象的相关性评分的最低分。
none
不使用匹配子对象的相关性评分。该查询为父文档分配的分数为 0
sum
将所有匹配子对象的相关性评分相加。
ignore_unmapped

(可选, boolean) 指示是否忽略未映射的path并且不返回任何文档而不是错误。默认为 false

如果设置为false,则当path是未映射的字段时,Elasticsearch 会抛出错误。

可以使用此参数来查询可能不包含path路径的多个索引。

注意

多级嵌套查询 (multi-level nested queries)

要了解多级嵌套查询是如何工作的,首先你需要一个包含嵌套字段的索引。 下面这个请求定义了具有嵌套字段makemodel的名为drivers的索引的映射。

PUT /drivers
{
    "mappings" : {
        "properties" : {
            "driver" : {
                "type" : "nested",
                "properties" : {
                    "last_name" : {
                        "type" : "text"
                    },
                    "vehicle" : {
                        "type" : "nested",
                        "properties" : {
                            "make" : {
                                "type" : "text"
                            },
                            "model" : {
                                "type" : "text"
                            }
                        }
                    }
                }
            }
        }
    }
}

接下来,添加并索引几个文档到索引drivers中:

# 添加第1个文档,指定id为1
PUT /drivers/_doc/1
{
  "driver" : {
        "last_name" : "McQueen",
        "vehicle" : [
            {
                "make" : "Powell Motors",
                "model" : "Canyonero"
            },
            {
                "make" : "Miller-Meteor",
                "model" : "Ecto-1"
            }
        ]
    }
}

# 添加第2个文档,指定id为2
PUT /drivers/_doc/2?refresh
{
  "driver" : {
        "last_name" : "Hudson",
        "vehicle" : [
            {
                "make" : "Mifune",
                "model" : "Mach Five"
            },
            {
                "make" : "Miller-Meteor",
                "model" : "Ecto-1"
            }
        ]
    }
}

现在,你可以使用多级嵌套查询来根据makemodel字段匹配文档:

GET /drivers/_search
{
    "query" : {
        "nested" : {
            "path" : "driver",
            "query" : {
                "nested" : {
                    "path" :  "driver.vehicle",
                    "query" :  {
                        "bool" : {
                            "must" : [
                                { "match" : { "driver.vehicle.make" : "Powell Motors" } },
                                { "match" : { "driver.vehicle.model" : "Canyonero" } }
                            ]
                        }
                    }
                }
            }
        }
    }
}

搜索请求返回如下响应:

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 3.7349272,
    "hits" : [
      {
        "_index" : "drivers",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 3.7349272,
        "_source" : {
          "driver" : {
            "last_name" : "McQueen",
            "vehicle" : [
              {
                "make" : "Powell Motors",
                "model" : "Canyonero"
              },
              {
                "make" : "Miller-Meteor",
                "model" : "Ecto-1"
              }
            ]
          }
        }
      }
    ]
  }
}