情况:我有一个严格映射的索引,我想从中删除一个不再使用的旧字段。因此,我使用映射创建了一个不包含该字段的新索引,然后尝试将数据重新索引到新索引中。
问题:重新索引时,出现错误,因为我试图将数据索引到映射中不可用的字段中。 因此,要解决此问题,我想先重新删除原始索引中所有文档中的该字段,然后才能重新索引。
PUT old_index/_doc/1
{
"field_to_delete" : 5
}
PUT old_index/_doc/2
{
"field_to_delete" : null
}
POST _reindex
{
"source": {
"index": "old_index"
},
"dest": {
"index": "new_index"
}
}
"reason": "mapping set to strict, dynamic introduction of [field_to_delete] within [new_index] is not allowed"
1。我发现有些地方建议这样做:
POST old_index/_doc/_update_by_query
{
"script": "ctx._source.remove('field_to_delete')",
"query": {
"bool": {
"must": [
{
"exists": {
"field": "field_to_delete"
}
}
]
}
}
}
但是,这与显式值为null
的文档不匹配,因此在此更新之后重新建立索引仍然会失败。
2。其他人(例如在其官方论坛中的Elastic团队成员)建议采取以下措施:
POST old_index/_doc/_update_by_query
{
"script": {
"source": """
if (ctx._source.field_to_delete != null) {
ctx._source.remove("field_to_delete");
} else {
ctx.op="noop";
}
"""
}
},
"query": {
"match_all": {}
}
}
但是,这也存在相同的问题-它不会删除具有显式值null
的第二个文档。
3。最后我可以做:
POST old_index/_doc/_update_by_query
{
"script": {
"source": "ctx._source.remove("field_to_delete");"}
},
"query": {
"match_all": {}
}
}
但是这将更新所有文档,并且对于较大的索引可能意味着部署期间的额外停机时间。
答案 0 :(得分:0)
最终我找到了正确的方法,因此我将其分享为常识:
POST old_index/_doc/_update_by_query
{
"script": {
"source": """
if (ctx._source.containsKey("field_to_delete")) {
ctx._source.remove("field_to_delete");
} else {
ctx.op="noop";
}
"""
}
},
"query": {
"match_all": {}
}
}