1. 简述
ES支持动态映射。即往ES中存储文档之前,可以不用预先定义索引、映射类型、字段等结构,ES内部会完成动态映射。
PUT data/_doc/1{ "count": 5 }
上述例子:动态映射建立索引data、文档映射类型_doc和名称为count且数据类型为long的字段。
2. 动态字段映射
2.1 概念说明
默认情况下,往文档中插入以前没有的字段(新字段)时,Elasticsearch会将新字段添加到类型映射中(动态映射)。
可以在文档(document)和对象(Object)级别禁用此行为(是否可以插入新字段),方法是将dynamic参数设置为false(忽略新字段)或strict(遇到未知字段时抛出异常)
如果开启了动态字段映射开关,ES将根据如下对应关系决定它的数据类型:
| 输入的json字段类型 | ES动态映射为的数据类型 | |
|---|---|---|
| null | 没有字段被添加(被忽略,相当于无效输入) | |
true 或者 false |
boolean类型 | |
| 浮点数(floating point number) | float类型 | |
| integer | long类型 | |
| 对象(Object) | object类型 | |
| 数组(array) | Array类型,元素类型取决于数组中的第一个null值。 | |
| 字符串(string) | - 如果值通过日期检测,则为date类型 - 如果值通过数字检测,则为float类型或long类型 - 否则,则为Text类型 |
默认日期字符串格式为:yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis
提示:表格中的字段类型支持动态字段映射,除此之外,其他数据类型必须通过显式映射(手动定义字段映射)
2.2 验证实例
2.2.1 新增文档
PUT dynamic_index/doc/1{"name": "八宝粥","desc": null,"price": 5.8,"month": 18,"info":{"place":"广东揭阳","category":"food"},"date":"2019/12/29 18:00:02","flavour":["sour","sweet","bitter","hot"],"model":["125.26","120","450ml"]}
2.2.1 查询字段定义
GET dynamic_index/_mapping
2.2.1 查询映射结果
从返回结果可以得出:
| 输入 | 映射 |
|---|---|
| “name”: “八宝粥”, |
“name” : { “type” : “text”, “fields” : { “keyword” : { “type” : “keyword”, “ignore_above” : 256 } } } |
| “desc”: null, | 没有被动态映射并添加到索引中(相当于无效输入) |
| “price”: 5.8, | “price” : { “type” : “float” } |
| “month”: 18, | “month” : { “type” : “long” }, |
| “date”:”2019/12/29 18:00:02”, | “date” : { “type” : “date”, “format” : “yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis” }, |
输入”desc”: null
“price”: 5.8,
“month”: 18,
{"dynamic_index" : {"mappings" : {"doc" : {"properties" : {"date" : {"type" : "date","format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"},"flavour" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}},"info" : {"properties" : {"category" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}},"place" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}}}},"model" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}},"month" : {"type" : "long"},"name" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}},"price" : {"type" : "float"}}}}}}
3. 日期检测
如果启用了date_detection(默认启用),则会检查新插入的字符串字段,看内容是否与在dynamic_date_formats指定的日期格式匹配,如果匹配,则字段映射为date类型,否则,映射为Text类型。
dynamic_date_formats的默认值(格式)为:
[ "strict_date_optional_time","yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z"]
3.1 验证实例1(映射为date类型)
3.1.1 新增文档
新增文档,日期字符串内容与默认日期格式一致
PUT date_detection_ok_index/_doc/1{"create_date": "2019/09/02 20:12:35"}
3.1.2 查询映射定义
GET date_detection_ok_index/_mapping
3.1.3 映射结果
{"date_detection_ok_index" : {"mappings" : {"_doc" : {"properties" : {"create_date" : {"type" : "date","format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"}}}}}}
3.2 验证实例2(映射为text类型)
3.2.1 新增文档
PUT date_detection_no_index/_doc/1{"create_date": "2019-09-02 20:12:35"}
3.2.1 查询映射定义
GET date_detection_no_index/_mapping
3.2.1 映射结果
{"date_detection_no_index" : {"mappings" : {"_doc" : {"properties" : {"create_date" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}}}}}}}
4. 禁用日期检测
在定义映射的时候,可以通过将date_detection设置为false,达到禁用动态日期检测,如下:
4.1 验证实例
4.1.1 新增定义
将该索引的映射中的date_detection属性设置为false。后续插入内容无论是何种日期格式,都将不会被检测并转换为date类型。
PUT disable_date_detection_index{"mappings": {"_doc": {"date_detection": false}}}
4.1.2 插入文档
PUT disable_date_detection_index/_doc/1{"create_date": "2019-09-02 20:12:35"}
4.1.3 查询映射定义
GET disable_date_detection_index/_mapping
4.1.4 映射结果
{"disable_date_detection_index" : {"mappings" : {"_doc" : {"date_detection" : false,"properties" : {"create_date" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}}}}}}}
5. 自定义检测日期格式
可以自定义 dynamic_date_formats 格式以支持自定义的日期格式:
5.1 新增定义(自定义日期格式)
PUT custom_date_format_index{"mappings": {"_doc": {"dynamic_date_formats": ["MM/dd/yyyy"]}}}
5.2 插入数据
示例1:插入日期字符串“13/31/2020”(日期不符合实际)
PUT /custom_date_format_index/_doc/1{"create_date":"13/31/2020"}
转换结果:不符合实际情况(13月)的日期字符串,尽管与自定义的日期检测格式形似,但是转换后的字段数据类型为TEXT
{"custom_date_format_index" : {"mappings" : {"_doc" : {"dynamic_date_formats" : ["MM/dd/yyyy"],"properties" : {"create_date" : {"type" : "text","fields" : {"keyword" : {"type" : "keyword","ignore_above" : 256}}}}}}}}
示例2:
插入日期字符串“05/31/2020”(日期符合实际)
PUT /custom_date_format_index/_doc/1{"birth_date":"05/31/2020"}
转换结果:日期格式字符串添加到es索引时,自动映射的字段类型为date类型,自定义日期检测生效
{"custom_date_format_index" : {"mappings" : {"_doc" : {"dynamic_date_formats" : ["MM/dd/yyyy"],"properties" : {"birth_date" : {"type" : "date","format" : "MM/dd/yyyy"}}}}}}
6.数字检测
ES 默认是禁用数字检测属性。我们可以在映射定义的时候,显式启用数字检测,例如:
6.1 新增定义
PUT numeric_detection_index{"mappings": {"_doc": {"numeric_detection": true}}}
6.2 插入文档
PUT numeric_detection_index/_doc/1{"my_float": "1.0","my_integer": "1"}
6.3 查询转换结果
查询
GET numeric_detection_index/_mapping
结果:
{"numeric_detection_index" : {"mappings" : {"_doc" : {"numeric_detection" : true,"properties" : {"my_float" : {"type" : "float"},"my_integer" : {"type" : "long"}}}}}}
