场景
在已经有大量数据的索引文档上,增加新字段
技术实现
一.更新索引映射
通过PUT请求显式定义新字段类型,确保后续写入的文档能被正确解析
json
PUT /文档名/_mapping
{
"properties": {
"字段名1": {
"type": ""
},
"字段名2": {
"type": ""
}
}
}
- 此操作仅定义字段类型,不会自动填充历史文档的默认值
二.设置默认值
1.写入时自动填充(新文档)
通过 Ingest Pipeline 在文档写入前自动添加默认值, 此操作仅对新写入数据生效
bash
PUT _ingest/pipeline/set_defaults
{
"processors": [
{
"set": {
"field": "like",
"value": 0
}
},
{
"set": {
"field": "disagree",
"value": 0
}
}
]
}
PUT /文档名/_settings
{
"index.default_pipeline": "set_defaults"
}
动态判断
bash
"script": {
"source": """
if (!ctx.containsKey('like')) { ctx.like = 0 }
if (!ctx.containsKey('disagree')) { ctx.disagree = 0 }
"""
}
2.批量回填历史数据(旧文档)
使用 _update_by_query
API 批量更新已有文档
bash
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
(亿级)