在使用es的过程中,有时候不小心在查询的时候应该使用Get操作,却使用了POST操作,这就会导致es的mapping里面多出一个无用的字段。或者在未定义字段类型时提交了新的数据字段,就会导致字段类型与预期的不一致,从而造成许多麻烦。
es是不支持删除单个字段的,尽管可以删除单个字段的所有数据,但是这个字段依然存在mapping声明中无法删除,这时候es的reindex api就该上场了,堪称救火神器!
reindex的最基本形式只是将文档从一个索引复制到另一个索引,例如:
POST _reindex
{
"source": {
"index": "twitter"
},
"dest": {
"index": "new_twitter"
}
}
上面操作会把twitter的数据复制一份到new_twitter中。
还可以这样使用:
POST _reindex
{
"source": {
"index": "twitter"
},
"dest": {
"index": "new_twitter",
"version_type": "external"
}
}
以上代码会从源保留版本,创建缺少的任何文档,并更新目标索引中具有旧版本的文档。
如果只是想单纯创建不存在的记录,可以:
POST _reindex
{
"conflicts": "proceed",
"source": {
"index": "twitter"
},
"dest": {
"index": "new_twitter",
"op_type": "create"
}
}
如果只想reindex部分数据,可以使用doc_type限制或者查询语句限制,例如:
POST _reindex
{
"size": 10000,(也可以控制操作的记录数量)
"source": {
"index": "twitter",
"type": "tweet",
"query": {
"term": {
"user": "kimchy"
}
}
},
"dest": {
"index": "new_twitter"
}
}
reindex可以指定_source字段进行操作,这样可以剔除不需要的字段或者改正字段类型(需要提前设置好新索引中的mapping,这样才能修改字段类型)。
例1:
POST _reindex
{
"source": {
"index": "twitter",
"_source": ["user", "tweet"]
},
"dest": {
"index": "new_twitter"
}
}
旧索引中的user,tweet字段数据reindex到新索引中。
例2:
POST _reindex
{
"source": {
"index": "twitter"
},
"dest": {
"index": "new_twitter",
"version_type": "external"
},
"script": {
"source": "if (ctx._source.foo == 'bar') {ctx._version++; ctx._source.remove('foo')}",
"lang": "painless"
}
}
在reindex过程中进行一些数据的修改。
例3:
POST _reindex
{
"source": {
"index": "test"
},
"dest": {
"index": "test2"
},
"script": {
"source": "ctx._source.tag = ctx._source.remove(\"flag\")"
}
}
修改字段名称,旧数据{"flag":"test"}改为{"tag":"test"}
在救火过程中,一般会用到索引别名alias, 这样当reindex完成之后,删除旧的索引,把索引别名映射到新的索引中来,这样就可以实现无缝切换。
PS: 务必注意先声明字段类型
远程reindex支持不同主机互相reindex,是个迁移数据的好方法,远程reindex需要在代码中指定服务器地址等信息,还需要把服务器地址添加到elasticsearch.yaml文件中的reindex.remote.whitelist白名单配置项中。
POST _reindex
{
"source": {
"remote": {
"host": "http://otherhost:9200",
"username": "user",
"password": "pass"
},
"index": "source",
"query": {
"match": {
"test": "data"
}
}
},
"dest": {
"index": "dest"
}
}