Elasticsearch可以根据待索引数据自动建立索引、自动定义映射类型。
1PUT data/_doc/1 2{ "count": 5 }
执行上述请求时,索引"data"不必预先创建,该API首先会自动创建索引data、类型映射_doc,其映射类型下包含字段count,其类型为long。自动根据文档的值推测其类型的过程,就是本文要重点描述的机制:动态类型映射机制。动态映射机制包含如下两种映射规则:
Dynamic field mappings
Dynamic templates
接下来就分别介绍上述两种动态映射规则。
字段动态映射
动态字段映射规则。默认情况下,当在文档中发现未存在的字段时,Elasticsea-rch将使用动态映射机制为字段添加映射定义。通过将映射参数dynamic设置为f-alse(忽略新字段)或strict(遇到未知字段时抛出异常),可以在文档和对象级别禁用此行为。
类型关系对应表
JSON datatype
Elasticsearch datatype
null
不会自动增加类型映射
true or false
boolean
floating
float
integer
long
object
object
array
根据数组中第一个非空值来判断
string
date、double、long、text(带有keyword子字段)
Date detection
日期类型检测,如果启用了date_dete-ction(默认),那么将检查新增的字符串字段,以查看它们的内容是否匹配dyn-amic_date_format中指定的任何日期模式。如果匹配其中任意一种格式,则添加字段映射时,字段的类型为date,并指定日期的format为匹配的模式。例如-:
1PUT my_index/_doc/12{3 "create_date": "2015/09/02"4}
由于create_date字段在json中的类型是字符串,但如果date_detection设置为t-rue,则creqate_date会映射为date类型而不是string类型。
可以在类型_type级别设置是否开启日期类型检测(date_detection),示例如下:
1PUT my_index2{3 "mappings": {4 "_doc": {5 "date_detection": false6 }7 }8}
定制日期类型检测格式
可以通过类型级别(_type)级别通过dyn-amic_date_formats参数来自定义日期检测格式,示例如下:
1PUT my_index 2{ 3 "mappings": { 4 "_doc": { 5 "dynamic_date_formats": ["MM/dd/yyyy"] 6 } 7 } 8} 910PUT my_index/_doc/111{12 "create_date": "09/25/2015"13}
numeric detection
数字类型检测。同样如果数字类型的值在JSON中是用字符串表示的话,如果开启日期类型检测,同样在创建映射时会映射为数字类型,而不是字符串类型-。
1PUT my_index2{3 "mappings": {4 "_doc": {5 "numeric_detection": true6 }7 }8}
默认情况下,numeric_detection为fal-se。
动态映射模板
Dynamic field mappings默认情况下根据elasticsearch支持的数据类型来推测参-数值的类型,而动态模板允许您改变字-段动态映射的默认行为。动态映射模板-通过如下方式进行定义:
1"dynamic_templates": [ // @12 {3 "my_template_name": { // @24 ... match conditions ... // @35 "mapping": { ... } // @46 }7 },8 ...9 ]
代码@1:在类型映射时通过dynamic_-templates属性定义动态映射模板,其类型为数组。
代码@2:定义动态映射模板名称。
代码@3:匹配条件,定义方式包括ma-tch_mapping_type、match、 match_p-attern、unmatch、path_match、path_-unmatch。
代码@4:匹配@3的字段使用的类型映射定义(映射参数为类型映射中支持的参数)。
动态类型映射模板的核心关键是匹配条件与类型映射,接下来按照匹配条件定义方式来重点讲解动态类型模板映射机制。
match_mapping_type
首先使用json解析器解析字段值的类型-,由于JSON不能区分long和integer,也不能区分double和float,所以它总是选-择更广泛的数据类型,例如5,在使用字段动态映射时,elasticsearch会将字段-动态映射为long而不是integer类型,那-如何将数字5动态映射为integer类型呢,利用match_mapping_type可以实现上述需求,例如,如果希望将所有整数字段-映射为整数而不是long,并将所有字符-串字段映射为文本和关键字,可以使用-以下模板:
1PUT my_index 2{ 3 "mappings": { 4 "_doc": { 5 "dynamic_templates": [ 6 { 7 "integers": { 8 "match_mapping_type": "long", 9 "mapping": {10 "type": "integer"11 }12 }13 },14 {15 "strings": {16 "match_mapping_type": "string",17 "mapping": {18 "type": "text",19 "fields": {20 "raw": {21 "type": "keyword",22 "ignore_above": 25623 }24 }25 }26 }27 }28 ]29 }30 }31}
一言以蔽之,match_mapping_type为字段动态映射(字段类型检测)得出的类型-建立一个映射关系,将该类型转换为m-apping定义中的类型。
match、unmatch
match参数使用模式匹配字段名,而un-match使用模式排除匹配匹配的字段。
match、unmatch示例如下:
1PUT my_index 2{ 3 "mappings": { 4 "_doc": { 5 "dynamic_templates": [ 6 { 7 "longs_as_strings": { 8 "match_mapping_type": "string", // @1 9 "match": "long_*", // @210 "unmatch": "*_text", // @311 "mapping": { // @412 "type": "long"13 }14 }15 }16 ]17 }18 }19}20PUT my_index/_doc/121{22 "long_num": "5", // @523 "long_text": "foo" // @624}
代码@1:表示该自动映射模板针对的字段为JSON解析器检测字段的类型为stri-ng的新增字段。
代码@2:字段名称以long_开头的字段-。
代码@3:排除字段名称以_text的字段。
代码@4:符合long_开头的字段,并且不是以_text结尾的字段,如果JSON检测为string类型的新字段,映射为long。
代码@5:long_num,映射类型为lon-g。
代码@6:long_text虽然也满足long_开-头,但是以_text结尾,故该字段不会映射为long,而是保留其JSON检测到的类型string,会映射为text字段和keyword-多字段(参考字段动态映射机制)。
match_pattern
使用正则表达式来匹配字段名称。
1"dynamic_templates": [ 2 { 3 "longs_as_strings": { 4 "match_mapping_type": "string", 5 "match_pattern": "regex", // @1 6 "match": "^profit_\d+$" // @2 7 "mapping": { 8 "type": "long" 9 }10 }11 }12]
代码@1:设置匹配模式为regex代表ja-va正则表达式
代码@2:java正则表达式
path_match、path_unmatch
path_match与path_unmatch的工作方式与match、unmatch一样,只不过path_-match是针对字段的全路径,特别是针--对嵌套类型(object、nested)。
下面一个示例:将name下的字段除了middle字段为copy到name属性并列的full_name字段中。
1PUT my_index 2{ 3 "mappings": { 4 "_doc": { 5 "dynamic_templates": [ 6 { 7 "copy_full_name": { 8 "path_match": "name.*", 9 "path_unmatch": "*.middle",10 "mapping": {11 "type": "text",12 "copy_to": "full_name"13 }14 }15 }16 ]17 }18 }19}20PUT my_index/_doc/121{22 "name": {23 "first": "Alice",24 "middle": "Mary",25 "last": "White"26 }27}
{name}、{dynamic_type}
{name}展位符,表示字段的名称。
{dynamic_type}:JSON解析器解析到的字段类型。
1PUT my_index 2{ 3 "mappings": { 4 "_doc": { 5 "dynamic_templates": [ 6 { 7 "named_analyzers": { // @1 8 "match_mapping_type": "string", 9 "match": "",10 "mapping": {11 "type": "text",12 "analyzer": "{name}"13 }14 }15 },16 {17 "no_doc_values": { // @218 "match_mapping_type":"",19 "mapping": {20 "type": "{dynamic_type}",21 "doc_values": false22 }23 }24 }25 ]26 }27 }28}2930PUT my_index/_doc/131{32 "english": "Some English text", 33 "count": 5 34}
代码@1:映射模板的含义为:对所有匹配到的字符串类型,类型映射为text,对应的分析器的名称与字段名相同,这个在使用时慎重,可能不存在同名的分析器,本例只是一个展示。
代码@2:对于匹配到的任何类型,其映射定义为类型为自动检测的类型,并且禁用doc_values=false。
更多文章请关注微信公众号:
本文分享自微信公众号 - 中间件兴趣圈(dingwpmz_zjj)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。