简介
Elasticsearch在遇到文档中以前未遇到的字段,可以使用dynamic mapping(动态映射机制) 来确定字段的数据类型并自动把新的字段添加到类型映射。
Elastic的动态映射机制可以进行开关控制,通过设置mappings的dynamic属性,
dynamic有如下设置项
- true:遇到陌生字段就执行dynamic mapping处理机制
- false:遇到陌生字段就忽略
- strict:遇到陌生字段就报错
```java
PUT /user
{
“settings”: {
“number_of_shards”: 3,
“number_of_replicas”: 0
},
“mappings”: {
“dynamic”: “strict”,
“properties”: {
} } }"name": {"type": "text"},
"address": {"type": "object", "dynamic": true}
会报错, 把没映射的age去掉就行了
PUT /user/_doc/1 { “name”: “lisi”, “age”: “20”, “address”: { “province”: “beijing”, “city”: “beijing” }
}
<a name="Dlwcd"></a>
# 映射的类型
ES是依靠JSON文档的字段类型来实现自动识别字段类型,支持的类型如下:

```json
POST /my_index/doc
{
"username":"whirly",
"age":22,
"birthday":"1995-01-01"
}
GET /my_index/_mapping
# 结果
{
"my_index" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"birthday" : {
"type" : "date"
},
"username" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
日期的自动识别
- dynamic_date_formats 参数为自动识别的日期格式,默认为 [ “strict_date_optional_time”,”yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z”]
- date_detection可以关闭日期自动识别机制 ```java PUT /my_index/_doc/1 { “note”: “2014-01-01” }
发现note自动映射为date类型
GET /my_index/_mapping
插入报错, 类型不对
PUT /my_index/_doc/2 { “note”: “Logged out” }
删除类型
DELETE /my_index
日期检测可以通过在根对象上设置 date_detection 为 false 来关闭, 然后现在类型就是text了
PUT /my_index { “mappings”: { “date_detection”: false } }
使用这个映射,字符串将始终作为 string 类型。如果需要一个 date 字段,必须手动添加。 Elasticsearch 判断字符串为日期的规则可以通过 dynamic_date_formats setting 来设置。
```java
# 自定义日期识别格式
DELETE /my_index
PUT /my_index
{
"mappings": {
"dynamic_date_formats": ["MM/dd/yyyy"]
}
}
# 符合我们日期规则, note将会是date类型
PUT /my_index/_doc/1
{
"note": "01/01/2014"
}
GET /my_index/_mapping
# 报错
PUT /my_index/_doc/1
{
"note": "2014-01-11"
}
# 如果一开始note插入数据不是符合规范的日期类型, 那后面note就会被识别为text类型
数字的自动识别
- 字符串是数字时,默认不会自动识别为整形,因为字符串中出现数字完全是合理的
numeric_detection 参数可以开启字符串中数字的自动识别
Dynamic templates
允许根据ES自动识别的数据类型、字段名等来动态设定字段类型,可以实现如下效果:
所有字符串类型都设定为keyword类型,即不分词
- 所有以message开头的字段都设定为text类型,即分词
- 所有以long_开头的字段都设定为long类型
- 所有自动匹配为double类型的都设定为float类型,以节省空间
Dynamic templates API
"dynamic_templates": [
{
"my_template_name": {
... match conditions ...
"mapping": { ... }
}
},
...
]
匹配规则一般有如下几个参数:
- match_mapping_type 匹配ES自动识别的字段类型,如boolean,long,string等
- match, unmatch 匹配字段名
- match_pattern 匹配正则表达式
- path_match, path_unmatch 匹配路径
模板按照顺序来检测;第一个匹配的模板会被启用。
例如,我们给 string 类型字段定义两个模板:
es :以 _es 结尾的字段名需要使用 spanish 分词器。
en :所有其他字段使用 english 分词器。
我们将 es 模板放在第一位,因为它比匹配所有字符串字段的 en 模板更特殊:
PUT /my_index2
{
"mappings": {
"dynamic_templates": [
{
"es": {
"match": "*_es",
"match_mapping_type": "string",
"mapping": {
"type": "text",
"analyzer": "spanish"
}
}
},
{
"en": {
"match": "*",
"match_mapping_type": "string",
"mapping": {
"type": "text",
"analyzer": "english"
}
}
}
]
}
}
GET /my_index2/_mapping
PUT /my_index2/_doc/1
{
"name_es": "testes",
"name": "es"
}
- 匹配字段名以 _es 结尾的字段
- 匹配其他所有字符串类型字段, match_mapping_type 允许你应用模板到特定类型的字段上,就像有标准动态映射规则检测的一样 (例 如 string 或 long)
- match参数只匹配字段名称,path_match 参数匹配字段在对象上的完整路径,所以 address.*.name 将匹配这样的字段
{ "address": { "city": { "name": "New York" } } }
# double类型的字段设定为float以节省空间
PUT my_index
{
"mappings": {
"_doc": {
"dynamic_templates": [
{
"integers": {
"match_mapping_type": "double",
"mapping": {
"type": "float"
}
}
}
]
}
}
}
自定义Mapping的建议
- 写入一条文档到ES的临时索引中,获取ES自动生成的Mapping
- 修改步骤1得到的Mapping,自定义相关配置
- 使用步骤2的Mapping创建实际所需索引
动态映射
PUT /library { "mappings": { "books": { "dynamic": "strict", "properties": { "title": {"type": "string"}, "name": {"type": "string", "index": "not_analyzed"}, "publish_date": {"type": "date","index": "not_analyzed"}, "price": {"type": "double"}, "number": { "type": "object", "dynamic": true } } } } }