在关系型数据库中,得先创建表,指定字段和字段类型,才能将数据插入表中。在ES中,索引就相当于表,文档就相当于记录,文档里面的字段就相当于表的字段,字段同样有数据类型。mapping就用来定义文档有哪些字段,这些字段如何存储和索引。
ES与关系型数据库不同之处在于,其不需要先定义表结构,而可以根据写入文档的内容,来推断字段和数据类型,创建索引结构,这就是dynamic mapping,动态映射的由来。这提供了极大的灵活性。
注:一个索引的字段数量有上限的,超过上限就会报错。
dynamic参数设置
按dynamic值,可分为下面三种模式
- 动态模式(dynamic:true),根据输入文档的内容,自动推断字段和类型,创建mapping
- 非动态模式(dynamic:false),无法根据输入文档的内容,自动创建mapping,需要手动创建mapping
- 严格模式(dynamic:strict),同非动态模式,区别在于,非动态模式,输入的文档中如果有字段不在mapping中,依然可以存储和读取,但是该字段不在mapping中,因此也无法根据该字段进行检索;但严格模式,无法存储,会直接报错,严格模式实际上就类似于关系型数据库中的表了。
动态模式(dynamic:true)
根据输入文档内容,自动创建mapping
step 1,es中还没有index1索引,直接往index1中写入文档1
step 2,这时候es中就有了索引index1,查询index1的mapping
可见age被推断成
long型
,string类型的name被推断成多字段类型,第一个类型是text
,第二个类型是keyword
。step 3,往已有的index1中写入文档2,出现了新的字段address
step 4,这时候address被自动加入索引mapping中
动态映射默认有一个规则,即请求中文档的什么json类型对应es中什么数值类型,也可以通过动态模板(dynamic template)来覆盖这个规则,实现自定义推测规则,具体可以参考ES官网。
上述字段age被推测成long类型,如果非要往age中写入string类型的值,则会报错。如下图所示
非动态模式(dynamic:false)
某些场景下,不需要进行动态映射,如需要显示设置mapping。
step 1,显式设置mapping,类似于关系型数据库建表操作
step 2,查询index2 mapping
step 3,插入文档1,字段与mapping保持一致
step 4,插入文档2,增加新的字段address
step 5,查询index2的mappings,看是否
address
会自动添加到mapping中step 6,查询全部文档,可见文档2中的
address
字段值,说明存储成功step 7,在address字段上进行匹配查询,无法匹配到结果,将索引指定为非动态映射后,无法进行自动推断,但是该字段的值是可以被存储,可是无法在该字段上进行查询。
严格模式(dynamic:strict)
step 1,设置严格模式
step 2,写入文档1,增加了一个字段
address
,直接报错,连写都写不进去了