Elasticsearch如何正确更新对象内的嵌套字段
问题成因
Elasticsearch Update API的doc参数默认不会将键名中的点号解析为嵌套字段的路径分隔符,而是会把带点的完整字符串当做顶级字段的字面量名称处理。
代码中直接传入"field.status": "B"时,ES不会进入field对象修改内部的status属性,只会在文档根节点新增一个名为field.status的平级字段,最终就出现原有嵌套字段未修改、平级新增字段的异常结果。
正确更新方式
以下两种方式均可以正确实现嵌套字段更新,兼容所有主流Elasticsearch版本:
- 嵌套对象传参(最推荐,写法简洁无额外配置)
按照文档实际的对象层级构造doc参数即可,ES会对传入的对象做深度合并,不会覆盖field下的其他已有字段:client.update({ index: elasticIndex, id: "anything", doc: { field: { status: "B" } } }).catch(console.error); - Painless脚本更新
如果需要实现复杂更新逻辑,也可以通过脚本直接操作文档_source元数据,直接指定嵌套字段路径赋值:client.update({ index: elasticIndex, id: "anything", script: { source: "ctx._source.field.status = params.newVal", params: { newVal: "B" } } }).catch(console.error);
常见误区提醒:第一种写法不会整体覆盖
field对象。ES的doc更新默认走深度合并逻辑,仅修改你传入的status字段,field下存储的其他属性会完整保留。
内容的提问来源于stack exchange,提问作者weera。
相关产品推荐
相关产品推荐

