es在已有历史数据的文档新增加字段操作_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
(亿级)