3.2.1.2.复合数据类型
分类 | 数据类型 |
Array 数组型 | 支持数组形式,不需要一个专有的字段数据类型 |
Object 对象型 | object数据类型:表现形式其实就是单一的JSON对象 |
Nested 嵌套型 | nested数据类型:表现形式是多个Object型组成的一个数组 |
Array 数组型
在Elasticsearch中,没有特定的array类型。默认情况下,任何字段都可以包含0个或者更多值,但是,所有array中的值必须具有相同的数据类型,例如:
字符串数组:
[“one”, “two”]
整数数组:
[1,2]
数组的数组:
[1, [2, 3]]
,等价于[1,2,3]
对象数组:
[ { "name": "Mary", "age": 12 }, { "name": "John", "age": 10 }]
注意
对象 数组并不能像你期望的那样工作:你不能独立于数组中的其它对象来查询每一个对象。如果想达到这个目的,你应该使用 nest 数据类型代替 object 数据类型
当自动添加一个字段,array的第一个值决定了字段的类型。所有接下来的值必须使用相同的数据类型或者必须至少能将他们转换为与它相同的类型
数组不支持混合的数据类型:[10, “some string”]
数组可以包含null值,这些值可以由配置的null_value替换或完全跳过。一个空的array []
被视为不存在的字段-无值的字段。
在文档中使用
array类型不需要提前做任何配置,天生就支持。
1 | tags 字段会动态添加为一个 string 字段 |
2 | lists 字段动态添加为一个 object 字段 |
3 | 第二个文档不包含 arrays,但是可以索隐为相同字段 |
4 | 这个查询,在 tags 字段查找 elasticsearch,会同时匹配到这2个文档 |
多值字段和倒排索引
事实上,所有字段类型天生支持多值字段源于 Luence。Lucene 设计为一个全文检索引擎。为了在一个大的文本快中查找特定单词,Lucene将文本标记为特定的术语,将每一个术语分别添加到倒排索引中。
这意味着即使是一个简单的文本也必须默认支持多值。当其它数据类型如数字或者日期被添加的时,他们使用和strings一样的数据结构,因此自然变为多值。
Object 对象型
JSON文档本质上是分层的:文档包含内部对象,内部对象本身还包含内部对象。
1 | 外层的文档是 JSON 对象 |
2 | 包含称为 |
3 |
|
在内部,这个文档被索引为一个简单的、扁平的键值对列表,如下所示:
上面文档的显式映射可以长这样:
1 | 映射的类型是一个对象类型,具有一个 |
2 |
|
3 |
|
不需要显式地将字段类型设置为object
类型,因为这是默认的类型。
object
字段的参数
object
字段的参数参数 | 说明 |
1 | 新属性是否应动态添加到现有对象。接受 true(默认),false 和 strict |
2 | 是否应该对对象字段给出的JSON值进行解析和索引(true,默认)或完全忽略(false) |
3 | 为对象中的所有属性设置默认的 |
4 | 对象内的字段,可以是任何数据类型,包括对象。可以将新属性添加到现有对象。 |
注意
如果你需要索引"对象的数组"而不是"单个的对象",可以使用
nested
数据类型。
Nested 嵌套型
nested
类型是一种对象类型的特殊版本,它允许索引对象数组,独立地索引每个对象。
如何使对象数组变扁平
内部类对象数组并不以你预料的方式工作。Lucene没有内部对象的概念,所以Elasticsearch将对象层次扁平化,转化成字段名字和值构成的简单列表。比如,以下的文档:
1 | user字段作为对象动态添加 |
在内部被转化成如下格式的文档:
user.first
和 user.last
扁平化为多值字段,alice 和 white 的关联关系丢失了。导致这个文档错误地匹配对 alice 和 smith 的查询
返回的两条数据
使用nested
字段对应object
数组
nested
字段对应object
数组如果你需要索引对象数组,并且保持数组中每个对象的独立性,你应该使用nested
对象类型而不是object
类型。nested
对象将数组中每个对象作为独立隐藏文档来索引,这意味着每个嵌套对象都可以独立被搜索:
1 |
|
2 | 该查询没有匹配,因为 |
3 | 该查询有匹配,因为 |
4 |
|
嵌套文档可以:
使用
nested
查询来搜索使用
nested
和reverse_nested
聚合来分析使用nested sorting来排序
使用nested inner hits来检索和高亮
nested
字段参数
nested
字段参数参数 | 说明 |
dynamic | 新属性是否应动态添加到现有对象。接受 true (默认), false 和 strict。 |
include_in_all | 为对象中的所有属性设置默认的 |
properties | 对象内的字段,可以是任何数据类型,包括对象。可以将新属性添加到现有对象。 |
注意 因为嵌套文档是作为单独的文档被索引的,所以嵌套文档只能被 nested 查询、nested / reverse_nested或者 nested inner hits 访问。 比如,一个 string 字段包含嵌套文档,嵌套文档中 index_options 设置为 offsets 以使用 postings highlighter,这些偏移量在主要的高亮阶段是不可用的。必须通过 nested inner hits 来进行高亮操作。
限制nested
字段的数量
nested
字段的数量索引一个包含 100 个 nested
字段的文档实际上就是索引 101 个文档,每个嵌套文档都作为一个独立文档来索引。为了防止过度定义嵌套字段的数量,每个索引可以定义的嵌套字段被限制在 50 个。
Last updated