Elasticsearch 6.7无法更新嵌套字段,如何正确指定嵌套字段?
Elasticsearch 6.7 嵌套字段更新错误修正
在Elasticsearch 6.7中尝试更新嵌套字段info.status时,执行以下请求后,并未更新info对象内的status字段,反而生成了一个名为info.status的顶级字段:
POST p_app/_update_by_query { "script": { "source": """ if (ctx._source?.info.status != null) { ctx._source.remove('info.status'); ctx._source.put('info.status', 'updated_value'); } """, "lang": "painless" }, "query": { "terms": { "_id": [ "1011" ] } } }
问题原因
Painless脚本中,ctx._source.put('info.status', ...)会把info.status当作完整的顶级字段名处理,而非解析为嵌套对象的路径。remove方法同样无法识别点分隔的嵌套路径,导致操作完全偏离预期。
正确写法
要操作嵌套字段,需直接访问嵌套对象的属性,而非通过点分隔的字符串作为键:
基础版本(确保info对象已存在)
POST p_app/_update_by_query { "script": { "source": """ if (ctx._source?.info != null && ctx._source.info.status != null) { // 直接修改嵌套对象的status属性 ctx._source.info.status = 'updated_value'; } """, "lang": "painless" }, "query": { "terms": { "_id": ["1011"] } } }
兼容info对象不存在的场景
如果需要处理info对象尚未创建的情况,可先初始化该对象:
POST p_app/_update_by_query { "script": { "source": """ // 初始化info对象(若不存在) if (ctx._source.info == null) { ctx._source.info = new HashMap(); } // 设置或更新status字段 ctx._source.info.status = 'updated_value'; """, "lang": "painless" }, "query": { "terms": { "_id": ["1011"] } } }
补充说明
- 无需调用
remove再put,直接赋值即可覆盖原有字段值 - 使用
ctx._source.info.status的写法能正确识别嵌套层级,直接操作目标字段
内容的提问来源于stack exchange,提问作者mahfuj asif
相关产品推荐
相关产品推荐

