映射(Mapping)类似于关系型数据库的Schema,会定义索引中在字段名称、类型以及倒排索引的相关设置。一个Mapping属于一个索引的Type,每个文档都有对应的Type。一个Type都有一个Mapping定义,从7.0开始不需要Mapping定义中指定Type信息。
映射类型
每个索引有一个或者多个映射类型(Type),用来在索引中将文档划分为不同的逻辑组。每个映射类型拥有:
1、元字段:用来定义如何处理文档的元数据。其中包括_index字段、_type字段、_id字段和_source字段。
2、字段/属性:每个映射类型包含不同数据类型的字段/属性。
在ES7.0之前,一个映射可以定义多个映射类型,如下所示:
上面2个映射类型:user_info和user_ext分别都有2个字段。从ES7.0开始,不建议对于一个索引创建多个映射类型,后续也可能禁止创建多个映射类型。
字段数据类型
ES支持一系列不同的数据类型来定义文档的字段,分为和兴数据、复杂数据、地理数据和专门数据。
核心数据类型
字符串:string
数字类型:long、integer、short、byte、double、float
日期类型:date
布尔类型:boolean
二进制:binary
复杂数据类型
数组类型:JSON数组
对象类型:JSON对象
嵌套类型:JSON对象的数组
地理数据类型
地理点类型:geo_point(经纬点)
地理形状类型:geo_shape(多边形的复杂地理形状)
特殊数据类型
IPv4类型:IP协议为IPv4的地址
完成类型:completion,提供自动补全的建议
单词计数类型:token_count,统计字符串中的单词数量
元字段
每个文档都有与之关联的元数据,其实为了保证系统正常运转的内置字段。如_index表示索引字段,_type表示映射类型字段、_id表示文档主键字段。这些字段都是以 _ 开头的,当索引被创建的时候,可以自定义一些元字段的行为。如:标识元字段、文档来源字段、索引元字段、路由元字段等。
标识元数据
_index:文档所属的索引
_uid:包含_type和_id的混合字段
_type:文档的映射类型
_id:文档的ID
文档来源元字段
_source:文档原始内容的JSON
_size:_source 元字段占用的字节数,通过 mapper-size插件提供
索引元字段
_all:索引所有字段的值
_field_names:所有包含非空值的字段
_timestamp:关联文档的时间戳,可以手动指定或自动生成
_ttl:定义文档被自动删除之前的存活时间
路由元字段
_parent:用于在映射类型之间创建父子关系
_routing:一个自定义的路由值,路由文档到一个特定的分片
其他元字段
_meta:应用特定的元字段
动态映射(Dynamic Mapping)
ES可以不事先创建好索引结构,可以在第一次写入文档时,自动创建索引映射。ES会根据第一次写入的文档,自动推测映射的字段类型,这种机制叫做动态映射。
类型自动识别
更改映射
对于Mapping的更改,可以分为2种情况:新增字段和更新字段。
新增字段
当dynamic设置为true时,如果新写入的文档中出现了新的字段,此时是可以动态更新Mapping设置的,也就是可以新增此字段,同时新增的字段也可以被搜索。
当dynamic设置为false时,文档可以被写入,但Mapping不会被更新,新增字段无法被检索,可以在_source 字段中保存新字段。
当dynamic设置为strict时,稳定写入失败。
更新字段
如果新的字段类型不匹配原有的字段Mapping,此时写入失败。此时解决的办法只能使用 Reindex API 进行索引的重建。
动态模板
动态模板可以在ES自动识别字段时,按照模板的规则匹配对应的类型。当在Kibana中写入如下文档时,会将age 字段识别为 text,birthday识别为date。
获取my_user 的mapping设置如下:
查看 my_user 的分片信息如下:
下面我们创建一个 templete_user 的Mapping 模板,匹配规则为 my_user*的索引,分片为1 副本为2,并且关闭日期类型的探测。
然后我们创建 my_user2 的索引文档,如下所示:
此时查看 mapping 和分片信息如下所示:对于birthday字段已经不是 date 类型了,并且副本数也变成了2个。
参考:《ElasticSearch技术解析与实战》、《极客时间:ElasticSearch核心技术与实战》