es在已有历史数据的文档新增加字段操作
新增字段设置默认值
场景
在已经有大量数据的索引文档上,增加新字段
技术实现
一.更新索引映射
通过PUT请求显式定义新字段类型,确保后续写入的文档能被正确解析
PUT /文档名/_mapping
{"properties": {"字段名1": {"type": ""},"字段名2": {"type": ""}}
}
- 此操作仅定义字段类型,不会自动填充历史文档的默认值
二.设置默认值
1.写入时自动填充(新文档)
通过 Ingest Pipeline 在文档写入前自动添加默认值, 此操作仅对新写入数据生效
PUT _ingest/pipeline/set_defaults
{"processors": [{"set": { "field": "like", "value": 0 }},{"set": { "field": "disagree", "value": 0 }}]
}PUT /文档名/_settings
{"index.default_pipeline": "set_defaults"
}
动态判断
"script": {"source": """if (!ctx.containsKey('like')) { ctx.like = 0 }if (!ctx.containsKey('disagree')) { ctx.disagree = 0 }"""
}
2.批量回填历史数据(旧文档)
使用 _update_by_query
API 批量更新已有文档
POST /service_bot_msg_chat_log/_update_by_query
{"script": {"source": """if (ctx._source.like == null) { ctx._source.like = 0 }if (ctx._source.disagree == null) { ctx._source.disagree = 0 }""","lang": "painless"},"query": {"bool": {"must_not": [{ "exists": { "field": "like" } },{ "exists": { "field": "disagree" } }]}},"timeout": "10m", // 防止超时"slices": 5 // 并行分片加速处理
}
- 性能优化
- 异步执行:添加
?wait_for_completion=false
转为后台任务
- 异步执行:添加
操作建议
- 新数据优先:优先配置 Ingest Pipeline,确保增量数据自动初始化
- 历史数据分治:根据数据量选择
_update_by_query
(百万级)或Reindex
(亿级)