本人小白一枚,最近在做Elasticsearch相关的项目,由于其中涉及到Mapping映射及索引数据迁移的相关任务,于是花了点时间琢磨了一下,一连翻操作之后总结到些许经验,特记录于此,供来者借鉴,不喜勿喷。
项目场景:
在Es运行过程中,随着业务的变动,修改Mapping的字段属性配置必不可少,以下场景得以说明。
场景1:某个Index使用了一段时间后需要修改某个字段的类型 例:把字段UserAddress的类型从text改为keyword。
场景2:某个Index使用了一段时间后发现某个字段冗余,为了减少存储空间需要删除。
场景3:某个Index使用了一段时间后由于业务的变动需要增加一个字段。
前言:
由于Elasticsearch创建Mapping后不能随便删改,只能增加字段,如需删改字段、修改字段类型等需要重建索引迁移数据,所以更改Mapping的实质是重建索引。
Elasticsearch使用Mapping的方式大致分为动态Mapping和Template两种方式。
动态Mapping:修改Mapping字段类型需要新建索引,数据迁移,属于重建索引。
模板Templete:修改Template后不会立即生效,对于已经存在的数据不会有影响,且只针对之后滚动出来的新的Index。
Template模板方式:
首先查看Template的配置(为了快速修改,不用手动去重写一遍模板)
GET _scripts/template_name
复制Template的配置并按实际需求进行修改
重新执行变更后的Template
总结:通过Template创建的Index可直接修改Template,执行后旧的索引不受影响,新的索引生成的时候就会按照更新后的Mapping配置来,如果需要某个索引立即生效,那就先删掉索引再建立索引(不推荐,会丢失数据)。
动态Mapping方式:
新建索引old_student
#1:创建old_student索引
PUT old_student
{
"mappings":{
"properties":{
"StuName":{
"type":"keyword"
},
"StuSex":{
"type":"short"
},
"StuMail":{
"type":"keyword"
},
"StuAge":{
"type":"integer"
}
}
},
"settings":{
"number_of_shards":3,
"number_of_replicas":1
}
}
查看索引old_student
#2:查看old_student索引mapping
GET old_student/_mapping
新增索引文档数据(测试数据)
#3:为old_student索引新增文档数据
PUT old_student/_doc/1
{
"StuName":"王五",
"StuMail":"wangwu@qq.com",
"StuSex":"1",
"StuAge":17,
"StuPhone":"18181866440"
}
此处省略新增多条数据代码。。。。
新增索引字段
#5:为old_student新增StuClass、StuAddress字段
PUT old_student/_doc/_mapping?include_type_name=true
{
"properties":{
"StuClass":{
"type":"keyword"
},
"StuAddress":{
"type":"keyword"
}
}
}
说明:新增字段后可立即添加测试数据,且新增字段后不会对之前的数据存在影响。
删除索引字段或修改字段类型
#6:删除字段StuClass的同时修改StuSex和StuAddress的字段类型
#6.1:直接修改方式 执行会报mapper [StuAddress] of different type, current_type [keyword], merged_type [text]异常,大体意思是不能直接修改字段类型
注:此方式如果不修改字段类型,只减少字段个数(模拟删除字段)虽然能执行成功,但实际上是无效的,索引Mapping字段依然存在。
PUT old_student/_mapping
{
"properties":{
"StuName":{"type":"keyword"},
"StuMail":{"type":"keyword"},
"StuSex":{"type":"keyword"},// type 从short改为keyword
"StuAge":{"type":"integer"},
"StuAddress":{"type":"text"}// type 从keyword改为text
}
}
#6.2:重建正确索引(new_student)方式(模拟 删除字段StuClass的同时修改StuSex和StuAddress的字段类型)
PUT new_student?include_type_name=true
{
"mappings":{
"info":{
"dynamic":false,//忽略陌生字段加入Mapping
"properties":{
"StuName":{"type":"keyword"},
"StuMail":{"type":"keyword"},
"StuSex":{"type":"keyword"},
"StuAge":{"type":"integer"},
"StuAddress":{"type":"text"}
}
}
}
}
#6.3:为old_student设置别名student
POST /_aliases
{
"actions": [
{
"add": {
"index": "old_student",
"alias": "student"
}
}
]
}
#6.4:将old_student数据迁移到new_student
注意:执行此步骤前提是设置新索引new_student禁止脏字段自动加入Mapping,否则将没有任何作用 详见#6.2重建索引
POST /_reindex
{
"source": {"index": "old_student"},
"dest": {"index": "new_student"}
}
#6.5:移除old_student别名并为新索引new_student设置相同的别名
POST /_aliases
{
"actions": [
{
"add": {
"index": "new_student",
"alias": "student"
}
},
{
"remove": {
"index": "old_student",
"alias": "student"
}
}
]
}
#6.6:删除old_student索引
DELETE old_student
#7:如果索引没有设置别名或者程序中没有使用别名来操作索引数据,数据迁移步骤如下 例:旧索引old_student。
#7.1:新建正确索引,例:new_student。
#7.2:迁移数据到新的索引。
#7.3:删除旧的索引(old_student)。
#7.4:此时新的索引已经存在数据,但索引名称不一样(系统操作的索引名都不一样),索引不存在重命名的操作。
#7.5:将新的索引(new_student)作为旧的索引,再创建一个以旧的索引(old_student),并将new_student数据迁移到old_student。
#7.6:删除新的索引(new_student)。
努力工作只是各取所需,摸鱼才叫赚钱。