Elasticsearch系列-Mapping
Mapping的定义
在之前的基本概念文章中提到过,我们知道mapping类似于关系型数据库中的Schema定义。作用如下:
- 可以定义索引中字段的名称;
- 可以定义字段的数据类型;
- 字段、倒排索引的相关配置。
Mapping有两种方式去定义数据:dynamic mapping 和explicit mapping。
Dynamic Mapping
dynamic mapping会自动创建mapping相关信息,会根据你写入的文档自动设置字段类型。这样你就不需要自己手动去一个一个的定义字段类型等信息。
字段类型转换规则:
JSON data type | Elasticsearch data type |
---|---|
null | 不会添加相关字段 |
true 或者 false | boolean |
double | float |
integer | long |
object | object |
string(匹配date detection) | date |
string(匹配numeric detection) | float或者long |
string(date detection,numeric detection都不匹配) | text 并且会创建keyword子字段 |
Date detection ES在自动转换类型的时候,会校验字符串是否匹配日期格式,匹配就设置字段类型为date,默认是打开状态。
numertic detection ES在自动转换类型的时候,会校验字符串是否匹配数字类型,匹配就设置字段类型为float或者long,默认是关闭状态。
我们可以通过字段dynamic设置,当文档新增字段时,Mapping进行相应操作:
类型 | 描述 |
---|---|
true | 字段新增会调整mapping信息(默认配置) |
false | 字段新增不会调整mapping信息,新字段不能进行索引和查询,但是会在_source中返回 |
strict | 字段信息会直接跑出异常报错 |
rutime | 字段新增会作为runtime fields类型调整mapping信息,但是不能被索引。 |
对已有字段,一旦已经有数据写入,就不再支持修改字段定义,不能修改mapping信息,如果希望改变字段类型,必须reindex API,重建索引
示例操作:
//插入一条数据信息
POST /layne-mapping/_doc/1
{
"id":"1",
"name":"layne",
"age": 27,
"isMan":true,
"birth":"1994/01/16",
"address":null
}
//获取layne-mapping索引mapping信息
GET /layne-mapping/_mapping
//返回信息:可以发现相关字段类型都进行了设置 address字段却没有,id字段也没有转成long类型
{
"layne-mapping" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"birth" : {
"type" : "date",
"format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
},
"id" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"isMan" : {
"type" : "boolean"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
//修改文档信息 新增字段alias
POST /layne-mapping/_update/1
{
"doc": {
"alias":"leilei"
}
}
//根据alias字段查询 可以查询到相应结果信息
GET /layne-mapping/_search?q=alias:leilei
//再次查看mapping信息,发现mapping信息中多了alias字段配置
GET /layne-mapping/_mapping
//修改mapping信息 设置dynamic为false
PUT /layne-mapping/_mapping
{
"dynamic":false
}
//修改文档信息 新增city字段
POST /layne-mapping/_update/1
{
"doc": {
"city":"shenzhen"
}
}
//根据city字段检索数据 没有匹配数据信息返回
GET /layne-mapping/_search?q=city:shenzhen
//根据id检索数据,可以在_source中看到有返回city字段信息
GET /layne-mapping/_doc/1
//再次查看mapping信息,发现没有配置city字段信息
GET /layne-mapping/_mapping
//修改mapping信息 设置dynamic为strict
PUT /layne-mapping/_mapping
{
"dynamic":"strict"
}
//再次修改文档信息 发现返回400错误 修改失败
POST /layne-mapping/_update/1
{
"doc": {
"weight": 180
}
}
//配置mapping信息 关闭date_detection,打开numeric_detection
PUT /layne-mapping-detection
{
"mappings":{
"date_detection":false,
"numeric_detection":true
}
}
//插入一条文档信息
POST /layne-mapping-detection/_doc/1
{
"birth":"1994/01/16",
"id":"1",
"age":27,
"name":"layne"
}
//查看mapping信息
GET /layne-mapping-detection/_mapping
//返回数据mapping信息 id字段自动转换成long类型 birth字段没有转变成date类型
{
"layne-mapping-detection" : {
"mappings" : {
"date_detection" : false,
"numeric_detection" : true,
"properties" : {
"age" : {
"type" : "long"
},
"birth" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"id" : {
"type" : "long"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
Explicit Mapping
通过上面的dynamic mapping操作知道,Elasticsearch会根据我们新增的文档进行自动字段转换,但是有些场景,我们是可以提前确定字段类型的,就比如关系型数据库一样,我们必须提前设置字段类型。对于这样的情景,我们就可以通过explicit mapping这种方式来处理,其实在进行dynamic mapping操作演示时,我们已经进行了explicit mapping方式操作了。explicit mapping方式的好处,比如:
- 提前定义好字段类型;
- 提前定义好date类型的数据格式;
- 定义一个新字段,通过文档现有字段处理得到。
演示操作:
//配置mapping信息 id字段为long类型 name和alias字段会拷贝到full_name字段,birth字段为date类型,city字段设置为不能索引
PUT /layne-mapping-explicit
{
"mappings": {
"_source": {},
"properties": {
"id":{"type":"long"},
"name":{"type": "text","copy_to": "full_name"},
"alias":{"type": "text","copy_to": "full_name"},
"birth":{"type": "date","format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"},
"city":{"type": "text","index": false},
"full_name":{"type": "text"}
}
}
}
//查看mapping配置信息
GET /layne-mapping-explicit/_mapping
//新增一条文档信息 但是没有full_name字段
POST /layne-mapping-explicit/_doc/1
{
"id":"123456",
"name":"layne",
"alias":"lei",
"birth":"1994/01/16",
"city":"shenzhen"
}
//查看文档数据信息
GET /layne-mapping-explicit/_doc/1
//通过full_name字段搜索,可以搜索到数据信息
GET /layne-mapping-explicit/_search?q=full_name:lei
//通过city字段搜索,不能搜索到数据信息
GET /layne-mapping-explicit/_search?q=city:shenzhen
//新增文档信息 这里填入非数字类型的id内容,添加报错,字段无法解析匹配
POST /layne-mapping-explicit/_doc/2
{
"id":"id_001",
"name":"nancy",
"alias":"lei",
"birth":"1995/01/16",
"city":"shanghai"
}