概述
Elasticsearch 的 mapping 在创建 indices 时即已确定,无法更改。那么,当我们需要更新 mapping 时,该如何是好呢?
基本思路
当我们在创建一条索引时,添加好 mapping 后,可设置一个 alias 指向该索引,然后生产环境采用该 alias 来索引数据。当然,如果没有这样做的话,建议趁早备份,修改 API 。
既然已创建的 indices 无法修改,我们可以重新创建一个新的 indices, 然后将原 indices 上的数据复制到新的 indices 上,再将 alias 指向新 indices。最后,删除原索引。
参数说明
当前索引名称: myindex_v1
生产索引名称:myindex
目标索引名称: myindex_v2
操作步骤
旧库的mapping结构
GET /myindex_v1/_mapping
需求:我们需要把上面的text转化为keyword类型
第一步:创建旧库索引别名
#增加别名
POST /_aliases
{
"actions" : [
{ "add" : { "index" : "myindex_v1", "alias" : "myindex" } }
]
}
第二步:创建新索引mapping
PUT /myindex_v2
{
"_all": {
"enabled": false
},
"mappings": {
"doc": {
"dynamic_templates": [
{
"string_as_keyword": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
],
"properties": {
"age": {
"type": "integer"
},
"sale": {
"type": "double"
},
"date": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
}
第三步:复制数据
#复制数据
POST /_reindex
{
"source": {
"index": "myindex_v1"
},
"dest": {
"index": "myindex_v2"
}
}
注意:如果数据量超大的话,复制数据所消费的时间比较多,所以请在构建索引前尽量考虑周全。
reindex方案请参考下面的连接
https://www.cnblogs.com/Ace-suiyuan008/p/9985249.html
POST _reindex?slices=5&refresh&wait_for_completion=false
{
"conflicts": "proceed",
"source": {
"index": "poc",
"type": "doc",
"size": 5000,
"_source":["CUSTNAME","CUSTNO","CUSTPHONE","ALARMLEVEL"]
},
"dest": {
"index": "new_twitter",
"op_type": "create",
"routing": "=cat"
},
"script": {
"source": "ctx._source.custname = ctx._source.remove(\"CUSTNAME\");ctx._source.custno = ctx._source.remove(\"CUSTNO\");ctx._source.custphone = ctx._source.remove(\"CUSTPHONE\");ctx._source.alarmlevel = ctx._source.remove(\"ALARMLEVEL\")"
}
}
复制数据比较快速的是根据分片数来复制,slices最好是ES的分片数的一倍或者整数倍(一倍最佳)。
wait_for_completion=false 快速返回一个任务ID,不需要等待复制执行完毕。
ctx._source.custname = ctx._source.remove(\"CUSTNAME\") 标识将原有字段中的CUSTNAME 修改为目标库中custname,修改多个字段使用分号分割
"size": 5000 表示每次拉取对的数量,此处根据你的环境调整
执行结果为
{
"task" : "Wv72OosPRIe3aDwcOzXWrg:8241018"
}
可以根据执行task查询当前任务执行情况
GET /_tasks/Wv72OosPRIe3aDwcOzXWrg:8241018
返回结果
{
"completed" : true,
"task" : {
"node" : "Wv72OosPRIe3aDwcOzXWrg",
"id" : 8241018,
"type" : "transport",
"action" : "indices:data/write/reindex",
"status" : {
"total" : 829162,
"updated" : 0,
"created" : 829162,
"deleted" : 0,
"batches" : 170,
"version_conflicts" : 0,
"noops" : 0,
"retries" : {
"bulk" : 0,
"search" : 0
},
"throttled_millis" : 0,
"requests_per_second" : -1.0,
"throttled_until_millis" : 0,
"slices" : [...]
},
"description" : """reindex from [poc][doc] updated with Script{type=inline, lang='painless', idOrCode='ctx._source.custname = ctx._source.remove("CUSTNAME");ctx._source.custno = ctx._source.remove("CUSTNO");ctx._source.custphone = ctx._source.remove("CUSTPHONE");ctx._source.alarmlevel = ctx._source.remove("ALARMLEVEL")', options={}, params={}} to [new_twitter]""",
"start_time_in_millis" : 1606897630282,
"running_time_in_nanos" : 34318304260,
"cancellable" : true,
"headers" : { }
},
"response" : {
"took" : 34317,
"timed_out" : false,
"total" : 829162,
"updated" : 0,
"created" : 829162,
"deleted" : 0,
"batches" : 170,
"version_conflicts" : 0,
"noops" : 0,
"retries" : {
"bulk" : 0,
"search" : 0
},
"throttled" : "0s",
"throttled_millis" : 0,
"requests_per_second" : -1.0,
"throttled_until" : "0s",
"throttled_until_millis" : 0,
"slices" : [...],
"failures" : [ ]
}
}
completed 表示是否执行完毕
response 有具体执行的情况
第四步:移除旧库添加新库
#移除旧库添加新库
POST /_aliases
{
"actions": [
{ "remove" : { "index" : "myindex_v1", "alias" : "myindex" } },
{ "add" : { "index" : "myindex_v2", "alias" : "myindex" } }
]
}
第五步:删除旧库(确认数据已经复制完毕)
#删除旧库
DELETE myindex_v1
第六步:检查新库
#查询
GET /myindex/_search
GET /myindex/_mapping
至此,更新mapping完成