Mapping
一、什么是Mapping
- mapping相当于数据库中的schema的定义,其作用有如下
- 定义索引中的字段名称;
- 定义字段的数据类型,比如数字型,字符串型,布尔。。。;
- 对字段,倒排索引进行相关的配置(analyzed or not analyzed,analyzer),即是否对该字段建立倒排索引等设置;
-
Mapping会吧json文档映射成lucene所需要的扁平格式;
-
一个mapping属于一个索引的type
- 每个文档都有一个type;
- 一个type有一个mapping定义;
- 从7.0开始,不需要在mapping中指定type的信息(因为一个索引只能有一个type);
二、mapping的常用字段类型
- 简单类型
- Text/keyword类型;
- date类型;
- long/float类型;
- boolean类型;
- IPV4&IPV6
- 复杂类型
- 对象类型/嵌套类型
- 特殊类型
- geo_point&geo_shape / percolator
三、Dynamic Mapping
- 什么是Dynamic Mapping
-
在写入文档的时候,如果索引不存在,则会自动创建索引;Dynamic Mapping就是一种在写入的过程中,es根据字段的数据信息;
自动分析出字段的数据类型;
-
当然,自动推断不是万能的,有可能会推断错误(比如对于地理位置信息),会导致某些功能不可使用;
-
类型的自动识别对应表
| JSON类型 | ES中的数据类型 |
| 字符串 | 1. 如果匹配了日期格式,那么就会设置为date类型; 2. 如果是数字字符串,默认当做text处理;但是可以配置数字设置为long/float,改为数字类型; 3. 设置为text字段,会自动增加一个keyword子字段; |
| 布尔值 | boolean |
| 浮点数 | float |
| 整数 | long |
| 对象 | object |
| 数组 | 由第一个非空元素的类型决定 |
| 空值 | 忽略 |
- 能否更改mapping的字段类型
新增加字段
- dynamic设置为true时,文档写入有新字段时,会将该字段加入倒排索引,并更新mapping;
- dynamic设置为false时,文档写入有新字段时,该字段不会建立索引(即不可用该字段搜索),也不会更新mapping,但是可以查询显示;
- dynamic设置为strict时,文档写入有新字段时,会写入失败;
对已有的字段修改
- 对已有的字段,一旦有数据写入,则不可更改;
- 如果希望改变字段的类型,则必须使用reindex API,重建索引
四、显示配置mapping
- 手动配置mapping的DSL
PUT users
{
"mappings" : {
"properties" : {
"firstName" : {
"type" : "text"
},
"lastName" : {
"type" : "text"
}
}
}
}
- 可以建立临时索引,写入样本数据,通过es自动分析建立起mapping;
- 然后通过mapping API查询出mapping设置,将其取出;
- 再对其内容进行修改,使用修改后的mapping配置建立你的索引;最后删除该临时索引;
- 控制当前字段是否可被索引搜索(字段index配置)
PUT users
{
"mappings" : {
"properties" : {
"firstName" : {
"type" : "text"
},
"lastName" : {
"type" : "text"
},
"mobile" : {
"type" : "text",
"index": false
}
}
}
}
- index该值默认为true(即可建立索引,并被索引搜索),设置为false的话,则不会对该字段建立索引,即不能通过该字段进行搜索;
- index_options(控制不同级别的倒排索引记录的内容);
| 参数内容 | 记录内容 |
|---|---|
| docs | 记录doc id(文档id) |
| freqs | 记录doc id 和 term frequencies(词频) |
| positions | 记录doc id / term frequencies(词频)/ term position(分词位置) |
| offsets | 记录doc id / term frequencies(词频)/ term position(分词位置)/ charactor offsets(偏移量) |
- 记录内容越多,占用的存储空间越大;
- 对null值进行搜索
PUT users
{
"mappings" : {
"properties" : {
"firstName" : {
"type" : "text"
},
"lastName" : {
"type" : "text"
},
"mobile" : {
"type" : "keyword",
"null_value": "NULL"
}
}
}
}
- 只有keyword类型可以指定null_value参数,实现对null值的搜索;
- copy_to设置
PUT users
{
"mappings": {
"properties": {
"firstName":{
"type": "text",
"copy_to": "fullName"
},
"lastName":{
"type": "text",
"copy_to": "fullName"
}
}
}
}
- 在7.0中替代了_all,用于满足一些特定的搜索需求;
- copy_to将被设置的字段的数值拷贝到指定的字段中;
- copy_to的目标字段不会被查询到_source中;
- 数组类型
- es中没有单独设置字段为数组类型,但是任何字段都可以包含多个相同类型的数值;
五、索引模板Index Template
- 概念
- 帮助设定Mappings和Settings,并按照一定的规则,自动匹配新创建的索引上应用模板;
- 模板只在一个被新创建的索引上才会产生作用,修改模板不会对已有的索引产生影响;
- 可以设定多个模板,对于匹配到多个模板的索引,这些模板的设置会被合并到一起,可以通过指定模板属性"order",来控制应用模板的顺序;
- 索引模板的应用顺序
- 首先应用ES默认的settings和mappings;
- 其次应用order数值低的Index Template设定;
- 再其次逐渐应用order数值高的Index Template设定,之前的设定会被覆盖;
- 最后创建索引时,应用用户所指定的settings和mappings,并覆盖之前模板中的设定;
- DSL应用举例模板
//创建索引模板
PUT /_template/template_test
{
//匹配以test开头的新创建的索引
"index_patterns": [
"test*"
],
//order设置为1
"order": 1,
//设置settings
"settings": {
"number_of_shards": 1,
"number_of_replicas": 2
},
//设置mappings
"mappings": {
"date_detection": false,
"numeric_detection": true
}
}
//查看索引模板信息
GET /_template/template_test
六、动态字段模板Dynamic Template
- 概念
- 根据ES识别的数据类型,再结合字段名称,来动态设置字段类型;
- 需要定义在某个索引的mapping中,且需要定义一个模板名称;
- 匹配的规则是一个数组(即可以设置多个匹配规则);
- 会对匹配到的字段设置mapping;
- 举例:所有字符串类型都设定为keyword,或者关闭keyword字段;is开头字段都设置成boolean;long_开头字段都设置成long类型;
- DSL应用举例模板
#设置动态字段模板
PUT my_index
{
"mappings": {
"dynamic_templates": [
//将字段名满足为is*且字段类型为字符串匹配的字段,设置为boolean类型
{
"strings_as_boolean": {
"match_mapping_type": "string",
"match": "is*",
"mapping": {
"type": "boolean"
}
}
},
//将字段类型为字符串匹配的字段,设置为keyword类型
{
"string_as_keywords": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
//新增文档
PUT my_index/_doc/1
{
"firstName": "Ruan",
"isVIP": "true"
}
//获取mapping
GET my_index/_mapping
//结果
{
"my_index" : {
"mappings" : {
"dynamic_templates" : [
{
"strings_as_boolean" : {
"match" : "is*",
"match_mapping_type" : "string",
"mapping" : {
"type" : "boolean"
}
}
},
{
"string_as_keywords" : {
"match_mapping_type" : "string",
"mapping" : {
"type" : "keyword"
}
}
}
],
//成功改变了这两个字段的数据类型
"properties" : {
"firstName" : {
"type" : "keyword"
},
"isVIP" : {
"type" : "boolean"
}
}
}
}
}