Skip to content
鼓励作者:欢迎打赏犒劳

es数据迁移

因为es的表结构一旦设置,就不容易修改,所以一般是创建一个新的表,然后迁移过去。

下面是一个 完整的 Elasticsearch Reindex 示例,用于将数据从旧索引迁移到新索引,并在迁移过程中 删除(移除)某个不需要的字段(比如 old_field)。


🎯 目标

  • 源索引:test_index
  • 目标索引:test_index_clean
  • 要删除的字段:old_field
  • 保留其他所有字段

✅ 步骤 1:创建目标索引(定义新的 mapping,不含 old_field

如果你希望完全继承原 mapping(只去掉某个字段),可以先获取原 mapping,手动删掉 old_field 后再创建新索引。

json
# 先查看原 mapping(可选)
GET /test_index/_mapping

假设原 mapping 是:

json
{
  "properties": {
    "name": { "type": "text" },
    "age": { "type": "integer" },
    "old_field": { "type": "keyword" }   // ← 要删除的字段
  }
}

创建新索引(不包含 old_field):

json
PUT /test_index_clean
{
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "age": { "type": "integer" }
      // 注意:没有 old_field
    }
  }
}

💡 如果字段很多,也可以用脚本自动过滤(后面会提到)。


✅ 步骤 2:使用 _reindex 迁移数据并移除字段

json
POST _reindex?wait_for_completion=false
{
  "source": {
    "index": "test_index"
  },
  "dest": {
    "index": "test_index_clean"
  },
  "script": {
    "source": "ctx._source.remove('old_field')"
  }
}

参数说明:

  • ctx._source:代表文档的原始 JSON 内容
  • .remove('old_field'):从文档中删除该字段
  • wait_for_completion=false:异步执行(适合大数据量);如果数据量小,可以设为 true 或省略

🔸 如果字段可能不存在(避免报错),可以用: (通常不会报错!!!)

json
"source": "if (ctx._source.containsKey('old_field')) { ctx._source.remove('old_field') }"

✅ 步骤 3:验证数据

json
# 查看新索引的文档数量
GET /test_index_clean/_count

# 随机查一条,确认 old_field 已消失
GET /test_index_clean/_search
{
  "size": 1
}

你应该看到返回的文档中 没有 old_field 字段


✅ 步骤 4(可选):切换别名 & 删除旧索引

如果你原来用的是别名(推荐做法),可以无缝切换:

为了避免中间状态出现问题,应该用一次请求完成“添加 + 删除”:

json
POST /_aliases
{
  "actions": [
    { "remove": { "index": "test_index", "alias": "my_data" } },
    { "add": { "index": "test_index_clean", "alias": "my_data" } }
  ]
}

如果你没有用别名,则需要通知应用方将写入/查询地址改为 test_index_clean


🧠 补充:批量删除多个字段?

只需在 script 中多次调用 remove

json
"script": {
  "source": """
    ctx._source.remove('field1');
    ctx._source.remove('field2');
    ctx._source.remove('field3');
  """
}

⚠️ 注意事项

  1. Reindex 不会复制索引设置(settings),如分片数、refresh_interval 等。如有需要,创建新索引时要一并设置。
  2. Reindex 是 CPU 和 I/O 密集型操作,建议在业务低峰期执行。
  3. 源索引在 reindex 过程中仍可读写,但新写入的数据不会自动同步到目标索引(除非你做滚动 reindex)。

✅ 总结

通过 _reindex + script.remove(),你可以:

  • 安全地“删除”字段(实际上是迁移时过滤掉)
  • 保留所有其他数据和结构
  • 实现 mapping 的“瘦身”或结构调整

这是 Elasticsearch 中 处理字段删除的标准做法

如果你告诉我具体的索引名和要删除的字段名,我可以帮你生成定制化的命令!

如有转载或 CV 的请标注本站原文地址