在ES中,index相当于数据库,type相当于表,而mapping则相当于表结构。
简单来讲,elasticsearch会在你插入数据的时候,自动根据数据类型设置mapping格式。而且因为一般文档数据都是不规则的,所以ES的mapping会根据插入值格式的变更,自动进行mapping变更。
虽然对于初学者而言,不需要了解mapping里面的各种特性,也可以很方便的使用ES的各种搜索功能,这也是ES推荐的——开箱即用。对初学者来说是十分友好的。
但是对于一个系统开发人员,必须要保证对系统非常熟悉,同时也要对数据的处理进行优化,这就需要进阶学习(如果你还在初级入门阶段,本文章中的内容你可以直接忽略,之后有兴趣再来阅读)。
言归正传,我们分以下几个部分来学习ES的mapping是怎么玩耍的。
同语言的数据类型相比,mapping还有一些其他的含义,mapping不仅告诉ES一个field中是什么类型的值, 它还告诉ES如何索引数据以及数据是否能被搜索到。
当你的查询没有返回相应的数据, 你的mapping很有可能有问题。当你拿不准的时候, 直接检查你的mapping。
如何查看当前数据库里面的mapping(你可以用postman或者浏览器访问以下链接):
http://127.0.0.1:9200/{index}/{type}/_mapping?pretty
如果index为: b2bware, type为:commerical_sku
http://127.0.0.1:9200/b2bware/commercial_sku/_mapping?pretty
以上是看某个type下的mapping结构,如果你要看整个库的mapping,URL请去掉type断即可,如:
http://127.0.0.1:9200/b2bware/_mapping?pretty
返回结果如:
{
"b2bware" : {
"mappings" : {
"commercial_sku" : {
"properties" : {
"message" : {
"type" : "string"
},
"price" : {
"type" : "string"
},
"tid" : {
"type" : "string"
},
"user" : {
"type" : "string"
}
}
}
}
}
}
第一种创建方式
就是直接插入数据,然后ES根据插入数据格式自动识别创建mapping,这种傻瓜式的方式非常简便,适合初学者。
如,创建一个ID为1 的新对象: http://127.0.0.1:9200/b2bware/newtable/1
{
"name":"test info ",
"content":"简单的json对象"
}
第二种创建方式
建index的时候,直接指定mappings,可以一次性创建多个mapping,如下面的代码所示:
URL:http://127.0.0.1:9200/b2bware PUT
参数body(放在post或者put请求的body部分)
{
"settings": {
"index": {
"number_of_shards": "10", //分10个片
"number_of_replicas": "1" //1个备份
}
},
"mappings": {
"commercial_sku": { //这是其中一个mapping,你还可以创建其他mapping
"_timestamp": { //这个配置可以删掉
"enabled": true
},
"properties": {
"message": {
"type": "string"
},
"price": {
"type": "string"
},
"tid": {
"type": "string"
},
"user": {
"type": "string"
}
}
}
}
}
第三种创建方式
已经创建了index(库已经创建),新增一个mapping
URL:http://127.0.0.1:9200/b2bware/article/_mapping PUT方式
注意,这种创建方式type[表名]是在URL中指定的,BODY部分只是指定了表结构:
{
"properties": {
"message": {
"type": "string"
},
"price": {
"type": "string"
},
"tid": {
"type": "string"
},
"user": {
"type": "string"
}
}
}
因为mapping只能进行追加修改,所以在建type的时候,最好清晰的知道表结构,否则数据变更起来比较麻烦,就像MySQL中已经有一个age存储的是字符串,突然有一天想改为int,因为存在历史数据,要变更就不那么容易。
所以ES的mapping调整只能追加字段,如下,新增一个 visitCount字段:
URL:http://127.0.0.1:9200/b2bware/article/_mapping PUT方式
{
"properties": {
"visitCount": {
"type": "integer"
}
}
}
mapping一旦创建之后,就无法修改,只能追加,如果要修改,就需要删除掉整个文档进行重建。
mappings : 在index(库)下创建时使用,下面可以有多个mapping 以下数据结构主要针对每个mapping进行说明:
一级属性 | 二级属性 | 三级属性 | 说明 |
---|---|---|---|
dynamic | 新增字段自动模式;true:表示自动识别新字段并创建索引,false:不自动索引新字段,strict:遇到未知字段,抛异常,不能存入 | ||
properties | 属性列表(类似数据库多个字段定义) | ||
{字段名} | 某个字段的定义 | ||
type | 数据类型,参见数据类型说明 | ||
index | 映射选型,参见映射选型说明 | ||
doc_values | 布尔值, 对not_analyzed字段,默认都是开启,分词字段不能使用,对排序和聚合能提升较大性能,节约内存 | ||
format | 如果数据类型为日期格式,传入值得时候是字符串,ES需要一个格式进行识别,如:yyyy-MM-dd HH:mm: ss | ||
analyzer | 分词器,如ik,ansj(中文分词) | ||
boost | 浮点型,字段级别的分数加权(权重) | ||
ignore_above | 超过多少字符,就不处理,分词性能损耗较大,对字符串较长的可不分词 | ||
null_value | 设置一些缺失字段的初始化值,只有string可以使用,分词字段的null值也会被分词 | ||
store | 是否单独设置此字段的是否存储而从_source字段中分离,默认是false,只能搜索,不能获取值 | ||
search_analyzer | 设置搜索时的分词器,默认跟ananlyzer是一致的,比如index时用standard+ngram,搜索时用standard用来完成自动提示功能 | ||
其它 | similarity,term_vector,norms,include_in_all,index_options,fielddata,ignore_malformed,precision_step |
一个典型的mapping对象的属性有:
{
"mappings": {
"my_type": {
//true:表示自动识别新字段并创建索引,false:不自动索引新字段,strict:遇到未知字段,抛异常,不能存入
"dynamic": "strict",
//属性列表
"properties": {
//一个strign类型的字段
"title": { "type": "string"},
"stash": {
"type": "object",
"dynamic": true
}
}
}
}
}
Elasticsearch自带的数据类型是Lucene索引的依据,也是我们做手动映射调整到依据。 映射中主要就是针对字段设置类型以及类型相关参数。
JSON基础类型如下:
字符串:string
数字:byte、short、integer、long、float、double、
时间:date
布尔值: true、false
数组: array
对象: object
Elasticsearch独有的类型:
多重: multi
经纬度: geo_point
网络地址: ip
堆叠对象: nested object
二进制: binary
附件: attachment
(3)复合类型
数组类型:没有明显的字段类型设置,任何一个字段的值,都可以被添加0个到多个,要求,他们的类型必须一致: 对象类型:存储类似json具有层级的数据 嵌套类型:支持数组类型的对象Aarray[Object],可层层嵌套
(4)地理类型
geo-point类型: 支持经纬度存储和距离范围检索
geo-shape类型:支持任意图形范围的检索,例如矩形和平面多边形
(5)专用类型 ipv4类型:用来存储IP地址,es内部会转换成long存储
completion类型:使用fst有限状态机来提供suggest前缀查询功能
token_count类型:提供token级别的计数功能
mapper-murmur3类型:安装sudo bin/plugin install mapper-size插件,可支持_size统计_source数据的大小
注意点:
Elasticsearch映射虽然有idnex和type两层关系,但是实际索引时是以index为基础的。 如果同一个index下不同type的字段出现mapping不一致的情况 虽然数据依然可以成功写入并生成并生成各自的mapping, 但实际上fielddata中的索引结果却依然是以index内第一个mapping类型来生成的。
某个属性(字段)的index可选值有:
analyzed:默认选项,以标准的全文索引方式,分析字符串,完成索引。
not_analyzed:精确索引,不对字符串做分析,直接索引字段数据的精确内容。
no:不索引该字段。