ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# Nested 原文链接 : [https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html#nested](https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html#nested) 译文链接 : [Nested](/display/Elasticsearch/Nested) 贡献者 : [彭秋源](/display/~pengqiuyuan),[ApacheCN](/display/~apachecn),[Apache中文网](/display/~apachechina) ## 嵌套数据类型 `nested `类型是一种对象类型的特殊版本,它允许索引对象数组,独立地索引每个对象。 ## 如何使对象数组变扁平 内部类对象数组并不以你预料的方式工作。Lucene没有内部对象的概念,所以Elasticsearch将对象层次扁平化,转化成字段名字和值构成的简单列表。比如,以下的文档: ``` curl -XPUT 'localhost:9200/my_index/my_type/1?pretty' -d' { "group" : "fans", "user" : [ // 1 { "first" : "John", "last" : "Smith" }, { "first" : "Alice", "last" : "White" } ] }' ``` `user `字段作为对象动态添加 在内部被转化成如下格式的文档: ``` { "group" : "fans", "user.first" : [ "alice", "john" ], "user.last" : [ "smith", "white" ] } ``` `user.first `和 `user.last `扁平化为多值字段,`alice `和 `white `的关联关系丢失了。导致这个文档错误地匹配对 `alice `和 `smith `的查询: ``` curl -XGET 'localhost:9200/my_index/_search?pretty' -d' { "query": { "bool": { "must": [ { "match": { "user.first": "Alice" }}, { "match": { "user.last": "Smith" }} ] } } }' ``` ## 使用`nested`字段对应`object`数组 如果你需要索引对象数组,并且保持数组中每个对象的独立性,你应该使用`nested`对象类型而不是`object`类型。`nested`对象将数组中每个对象作为独立隐藏文档来索引,这意味着每个嵌套对象都可以独立被搜索: ``` curl -XPUT 'localhost:9200/my_index?pretty' -d' { "mappings": { "my_type": { "properties": { "user": { "type": "nested" // 1 } } } } }' curl -XPUT 'localhost:9200/my_index/my_type/1?pretty' -d' { "group" : "fans", "user" : [ { "first" : "John", "last" : "Smith" }, { "first" : "Alice", "last" : "White" } ] }' curl -XGET 'localhost:9200/my_index/_search?pretty' -d' { "query": { "nested": { "path": "user", "query": { "bool": { "must": [ { "match": { "user.first": "Alice" }}, { "match": { "user.last": "Smith" }} // 2 ] } } } } }' curl -XGET 'localhost:9200/my_index/_search?pretty' -d' { "query": { "nested": { "path": "user", "query": { "bool": { "must": [ { "match": { "user.first": "Alice" }}, { "match": { "user.last": "White" }} // 3 ] } }, "inner_hits": { // 4 "highlight": { "fields": { "user.first": {} } } } } } }' ``` | 1 | `user` 字段映射为 `nested` 类型而不是 `objec t`类型 | | 2 | 该查询没有匹配,因为 `Alice` 和 `Smith` 不在同一个嵌套类中 | | 3 | 该查询有匹配,因为 `Alice` 和 `White` 在同一个嵌套类中 | | 4 | `inner_hits` 可以高亮匹配的嵌套文档 | 嵌套文档可以: | 1 | `使用 `[nested](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html "Nested Query")` `查询来搜索 | | 2 | 使用 `[nested](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html "Nested Aggregation")` 和 [`reverse_nested`](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-reverse-nested-aggregation.html "Reverse nested Aggregation")聚合来分析 | | 3 | 使用 [nested sorting](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html#nested-sorting "Sorting within nested objects.")来排序 | | 4 | 使用 [nested inner hits](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-inner-hits.html#nested-inner-hits "Nested inner hits") 来检索和高亮 | ## `nested `字段参数 | 参数 | 说明 | | dynamic | 新属性是否应动态添加到现有对象。接受 true (默认), false 和 strict。 | | include_in_all | 为对象中的所有属性设置默认的 `include_in_all` 值,对象本身没有添加到 _all 字段。 | | properties | 对象内的字段,可以是任何数据类型,包括对象。可以将新属性添加到现有对象。 | 注意 因为嵌套文档是作为单独的文档被索引的,所以嵌套文档只能被 `nested` 查询、`nested / reverse_nested`或者 `nested inner hits` 访问。 比如,一个 `string` 字段包含嵌套文档,嵌套文档中 `index_options` 设置为 `offsets` 以使用 postings highlighter,这些偏移量在主要的高亮阶段是不可用的。必须通过 `nested inner hits` 来进行高亮操作。 ## 限制`nested`字段的数量 索引一个包含 100 个 `nested `字段的文档实际上就是索引 101 个文档,每个嵌套文档都作为一个独立文档来索引。为了防止过度定义嵌套字段的数量,每个索引可以定义的嵌套字段被限制在 50 个。