elasticsearch mappings之dynamic的三种状态
前言
一般的, mapping 可以分为 动态映射(dynamic mapping) 和 静态(显示) 映射 (explicit mapping) 和精准(严格) 映射(strict mapping)
具体由dynamic 属性控制
动态映射(dynamic: true)
创建一个索引
PUT m1 { "mappings": { "doc":{ "properties": { "name": { "type": "text" }, "age": { "type": "long" } } } } }
通过 GET m1/_mapping 看一下 mappings 信息:
{ "m1" : { "mappings" : { "doc" : { "dynamic" : "true", "properties" : { "age" : { "type" : "long" }, "name" : { "type" : "text" } } } } } }
添加一些数据,并且新增一个sex字段:
PUT m1/doc/1 { "name": "小黑", "age": 18, "sex": "不详" }
此时看下 mappings
{ "m1" : { "mappings" : { "doc" : { "dynamic" : "true", # ES 默认允许添加新的字段 "properties" : { "age" : { "type" : "long" }, "name" : { "type" : "text" }, "sex" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } } } } } } }
注意: mappings 一旦创建,则无法修改。因为Lucene 生成倒排索引后就不能改了
静态映射(dynamic:false)
现在,我们将 dynamic 值设置为 false
PUT m2 { "mappings": { "doc":{ "dynamic":false, "properties": { "name": { "type": "text" }, "age": { "type": "long" } } } } }
现在测试一下false 和 true 有什么区别
PUT m2/doc/1 { "name": "小黑", "age":18 } PUT m2/doc/2 { "name": "小白", "age": 16, "sex": "不详" }
第二条数据相对于第一条数据,多了一个sex属性,我们可以用sex来做为条件查询一下:
GET m2/doc/_search { "query": { "match": { "sex": "不详" } } }
结果为空 为什么呢?
我们再此查一下mappings 结果在mappings中并没有 sex字段的映射关系。
所以查不到。 但是存储时会存储该字段。 相当于能写 不能 查
严格模式(dynamic:strict)
同样 创建一个 mappings
PUT m3 { "mappings": { "doc": { "dynamic": "strict", "properties": { "name": { "type": "text" }, "age": { "type": "long" } } } } }
添加两篇文档
PUT m3/doc/1 { "name": "小黑", "age": 18 } PUT m3/doc/2 { "name": "小白", "age": 18, "sex": "不详" }
第一篇文档添加和查询都没问题。但是,当添加第二篇文档的时候,就报错了
也就是 连写都不能写
小结
- 动态映射(dynamic:true):动态添加新的字段(或缺省)。
- 静态映射(dynamic:false):忽略新的字段。在原有的映射基础上,当有新的字段时,不会主动的添加新的映射关系,只作为查询结果出现在查询中。
- 严格模式(dynamic: strict):如果遇到新的字段,就抛出异常。
一般静态映射用的较多。就像HTML
的img
标签一样,src
为自带的属性,你可以在需要的时候添加id
或者class
属性。
当然,如果你非常非常了解你的数据,并且未来很长一段时间不会改变,strict
不失为一个好选择。