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查询来搜索 |
| 2 | 使用
[nested](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html "Nested Aggregation")
和 reverse_nested
聚合来分析 |
| 3 | 使用 nested sorting来排序 |
| 4 | 使用 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 个。