ElasticSearch使用ctx._source访问对象字段时触发null_pointer_exception
问题根源分析
你遇到的空指针异常,核心原因是索引映射定义的是扁平字段而非嵌套对象,但更新脚本错误地将customers当作嵌套对象来访问。
细节拆解:
- 你的映射中,
customers.id、customers.name、customers.company是独立的顶级字段(字段名包含点符号,并非嵌套对象的属性)。 - 插入文档时,你使用的是
"customers.company"这种带点的键名,因此文档的_source结构是:
而不是你脚本中假设的嵌套结构:{ "customers.id": 2, "customers.company": "apple", "customers.name": "james" }{ "customers": { "id": 2, "company": "apple", "name": "james" } } - 当脚本执行
ctx._source.customers.company时,ctx._source.customers并不存在(返回null),后续访问company自然触发空指针异常。
正确的更新脚本写法
要修改带点符号的字段,在Painless脚本中需要用方括号+字符串的方式访问字段名:
POST /customer-index/_update_by_query { "script": { "source": "ctx._source['customers.company'] = params.company", "lang": "painless", "params": { "company": "samsung" } }, "query": { "term": { "customers.id": 2 } } }
(可选)改为嵌套对象的规范写法
如果你原本期望customers是嵌套对象,需要重新定义映射并插入结构化文档:
1. 删除原有索引后,创建嵌套结构的映射:
PUT /customer-index { "mappings":{ "properties":{ "customers": { "type": "object", "properties": { "id": {"type": "long"}, "name": {"type": "text", "norms": false}, "company": {"type": "text", "norms": false} } } } } }
2. 插入嵌套结构的文档:
PUT /customer-index/_doc/2 { "customers": { "company": "apple", "id": 2, "name": "james" } }
此时你原来的更新脚本ctx._source.customers.company = params.company就能正常执行了。
内容的提问来源于stack exchange,提问作者Ankit Pandoh
相关产品推荐
相关产品推荐

