动态映射
在Elasticsearch中可以不事先建好索引结构,在使用的时候可以直接插入文档到索引中,系统会根据文档的内容自动进行索引结构的动态映射,这样就极大地简化了索引的操作。
自动检测添加新类型和字段,被称为动态映射。可以根据目的自定义动态映射的规则:
- _default_:用于创建新映射类型的基础映射
- 动态字段映射:控制动态字段检测规则
- 动态模板:自定义规则来匹配动态添加字段的映射
禁用动态类型创建:
动态类型创建可以通过设置index.mapper.dynamic
为false来禁用,无论是在配置文件config/elasticsearch.yml中进行设置还是在每个索引中进行设置:
PUT /_settings
{
"index.mapper.dynamic":false//对所有的索引禁用动态类型创建
}
_default_映射
默认映射,用作每个新映射类型的基础映射,可以通过在索引增加名为_default_的映射类型来自定义:
PUT /myindex2
{
"mappings": {
"_default_":{
"_all":{"enabled":false}
},
"user":{},
"blogpost":{
"_all":{"enabled": true}
}
}
}
- _default_映射禁用了_all字段
- user映射从_default_映射继承了设置
- blogpost映射重写了默认设置,启动了_all字段
_default_映射可以在索引创建之后进行修改,新的默认映射只会影响到之后创建的映射类型。
动态字段映射
这些是仅有的可以动态添加的字段数据类型。所有其它的数据类型都必须被明确地添加到映射中。
除了下面列出的选项,可以通过动态模板自定义更多的动态字段映射规则:
1. 日期检查
如果启用日期检查(默认),新的字符串字段的内容会被检查是否匹配任何dynamic_date_formats中指定的日期格式。如果发现匹配,新的日期字段会以相同的格式添加。
//dynamic_date_formats默认值是:
["strict_date_optional_time","yyyy/MM'dd HH:mm:ss Z|| yyyy/MM/dd Z"]
2. 禁用日期检查
通过设置date_detection的值为false来禁用动态日期检查:
PUT /myindex2
{
"mappings":{
"test2":{"date_detection":false}
}
}
3. 自定义日期检查格式
PUT /myindex2
{
"mappings":{
"test2":{"dynamic_date_formats":["MM/dd/yyyy"]}
}
}
4. 数字检查
因为JSON支持浮点型和整型数据类型,一些应用或语言有时会作为字符串传递数字,通常的解决方式是明确这些字段映射,但是可以启用数字检查(默认禁用)来自动做类型转换:
PUT /myindex2
{
"mappings":{
"test2":{"number_detection":true}
}
}
#### 动态模板
动态模板可以定义自定义映射用来动态添加字段,基于以下参数:
- 通过Elasticsearch金鑫改数据类型检查,利用match_mapping_type参数
- 字段名,利用match and unmatch 或 match_pattern参数
- 字段全路径,利用path_match and path_unmatch参数
原始字段名{name}和数据类型检查{dynamic_type}模板变量可以作为占位符在映射标准中。
`注意:`动态字段映射仅在字段包含具体值(不为null或空数组)的时候添加。这意味着如果在dynamic_template中有null_value选项,第一个文档中被索引的字段有具体的值之后,null_value才会起作用。
动态模板被指定为命名的对象数组:
```js
PUT /myindex2
{
"mappings": {
"dynamic_templates":[
{
"my_template_name":{
... match conditions ...
"mapping":{...}
}
},
...
]
}
}
- 模板名可以是任何字符串值
- 匹配条件可以包含所有的:match_mapping_type、match、match_pattern、unmatch、path_match、path_unmatch。
- mapping包含匹配到的字段需要使用的映射值
模板顺序指定——第一个匹配到的模板起作用。新的模板可以用增加接口添加到列表的末尾。如果新的模板和已经存在的模板有相同的名字,旧版本会被替换掉。
1. match_mapping_type
match_mapping_type匹配数据类型,通过动态字段映射检查,换句话就是Elasticsearch认为字段需要拥有的数据类型。
只有下面的数据类型可以被自动检查:
- boolean
- date
- double
- long
- object
- string
也可以接受*来匹配所有的数据类型。
示例:需要映射所有整数型字段为integer而不是long,以及所有的可分词和不可分词的字符串型字段,可以使用下面的模板:
PUT /myindex2
{
"mappings": {
"test2":{
"dynamic_templates":[
{
"integers":{
"match_mapping_type":"long",//如果匹配为long,改为integer
"mapping":{"type":"integer"}
}
},
{
"text":{
"match_mapping_type":"string",
"mapping":{
"type":"string",
"fields":{
"raw":{"type":"string", "index":false, "ignore_above":256}
}
}
}
}
]
}
}
}
2. match和unmatch
match参数使用匹配字段名称的方式,unmatch使用排除match匹配的字段的方式。
示例:匹配所有字符串型字段名字以long_开头并排除以_text结束的字段,索引这些字段为长整型字段:
PUT /myindex2
{
"mappings": {
"test2":{
"dynamic_templates":[
{
"longs_as_strings":{
"match_mapping_type":"string",
"match":"long_*",
"unmatch":"*_text",
"mapping":{"type":"long"}
}
}
]
}
}
}
3. match_pattern
match_pattern参数支持完整的Java正则表达式匹配字段名而不是简单的通配符:
"match_pattern":"regex"
4. path_match和path_unmatch
工作方式与match和unmatch相同,但是在字段全路径上进行操作,不仅仅是在最终的名字上:
PUT /myindex2
{
"mappings": {
"test2":{
"dynamic_templates":[
{
"full_name":{
"path_match":"name.*",
"path_unmatch":"*.middle",
"mapping":{"type":"string", "copy_to":"full_name"}
}
}
]
}
}
}
5. {name}和{dynamic_type}
占位符会被映射中的字段名和字段类型替换。
示例:设置所有的字符型字段使用与字段同名的分析器,禁用所有非字符型字段的doc_values参数:
PUT /myindex2
{
"mappings": {
"test2":{
"dynamic_templates":[
{
"named_analyzers":{
"match_mapping_type":"string",
"match":"*",
"mapping":{"type":"string","analyzer":"{name}"}
}
},
{
"no_doc_values":{
"match_mapping_type":"*",
"mapping":{"type":"{dynamic_type}", "doc_values":false}
}
}
]
}
}
}
重写默认模板
可以重写所有索引的默认映射,也可以通过在索引模板中指定_default_类型映射重写映射类型。
示例:为了对所有新索引中的类型禁用_all字段,可以创建下面这样的索引模板:
PUT /_template/disable_all_field
{
"disable_all_field":{
"order":0,
"template":"*",
"mappings":{
"_default_":{
"_all":{
"enabled":false
}
}
}
}
}