文档更新接口是什么
更新接口支持三种写法:doc 部分字段更新、script 脚本更新,以及 upsert 语义。doc_as_upsert 让文档不存在时按 doc 内容插入,是幂等写入的常用写法。底层机制是「取回 _source、修改、重新索引」,因此高并发下需要用 retry_on_conflict 缓解版本冲突,而不是靠加锁。
基本信息
| 部分更新 | { "doc": { "views": 10 } } 只覆盖给定字段 |
|---|---|
| 脚本更新 | script 配合 painless 修改字段或数组元素 |
| upsert | 文档缺失时插入 upsert 内容 |
| doc_as_upsert | 把 doc 内容同时当作插入内容 |
| 重试 | retry_on_conflict 指定冲突重试次数 |
| 适用版本 | Elasticsearch 7.x / 8.x |
典型使用场景
- 统计字段递增:用脚本对计数器累加
- 状态流转:只改状态字段而不动其他内容
- 幂等写入:doc_as_upsert 保证不存在时插入
- 数组元素追加或移除,用脚本处理
- 批量修正字段值,配合 _bulk 提高吞吐
- 与外部系统对账后回写核对标记
示例
示例
POST /my-index/_update/1
{
"doc": { "views": 10, "updated_at": "2026-10-01" },
"doc_as_upsert": true # 不存在则按 doc 插入
}
POST /my-index/_update/1
{
"script": {
"source": "ctx._source.views += params.n", # 原子累加
"params": { "n": 1 }
},
"retry_on_conflict": 3
}写法对照
| 写法 | 行为 | 注意点 |
|---|---|---|
| doc | 覆盖给定字段 | 数组是整体替换而非追加 |
| script | 按脚本修改 | 默认只能改 _source 已有结构 |
| upsert | 不存在时插入指定内容 | 与 doc 可并存 |
| doc_as_upsert | 复用 doc 作为插入内容 | 常用于幂等写入 |
| retry_on_conflict | 冲突时自动重试 | 次数不宜过大 |
更新是取回再重建索引的过程,不是原地修改;高并发下用 retry_on_conflict 缓解版本冲突,同时要注意重试次数过高会放大压力。
doc 更新会整体替换同名字段的值,数组不会追加而是覆盖;需要追加元素必须使用脚本。
关闭 _source 的索引只能用脚本更新,且脚本无法读取原值,更新难度大幅上升,映射设计时不要轻易关闭 _source。
更新返回 result 为 noop 表示提交的 doc 与原值相同、没有实际改动;这属于正常结果,排查「更新没生效」时先看它。