OpenSearch 2.3.0统计nested类型parcels数组总元素数的问题
问题:统计OpenSearch中nested类型数组的总元素数
环境与需求
- OpenSearch版本:2.3.0
- 索引映射包含nested类型字段
parcels,映射片段如下:
"parcels": { "type": "nested", "properties": { ... } },
- 需求:统计索引中所有文档的
parcels数组元素总数,例如3个文档分别包含2、3、1个parcels元素时,聚合结果需返回6。
尝试的脚本及错误
我使用了以下聚合脚本:
{ "size": 0, "aggs": { "total_parcels": { "sum": { "script": { "source": "ctx._source.parcels.length" } } } } }
但脚本编译失败,错误信息如下:
"reason": { "type": "script_exception", "reason": "compile error", "script_stack": [ "ctx._source.parcels.length", " ^---- HERE" ], "script": "ctx._source.parcels.length", "lang": "painless", "position": { "offset": 19, "start": 0, "end": 26 }, "caused_by": { "type": "illegal_argument_exception", "reason": "cannot resolve symbol [ctx._source.parcels.length]" } }
错误原因
错误出在脚本的访问逻辑:
- Painless脚本中访问文档源数据需用
params._source,而非ctx._source; - 未添加空值判断,若某个文档无
parcels字段会触发空指针异常; - 虽然nested类型字段存储时会拆分为独立子文档,但_source中仍保留原数组结构,只要_source未被禁用,即可直接访问数组长度。
正确实现方式
方式一:利用nested聚合统计(适用于所有场景,包括_source被禁用)
通过nested聚合遍历所有parcels子文档,再用value_count统计子文档数量,总数即为所有parcels元素的个数:
{ "size": 0, "aggs": { "parcels_nested": { "nested": { "path": "parcels" }, "aggs": { "total_parcels": { "value_count": { "field": "parcels.某个必存在的字段" // 替换为parcels映射中实际存在的必填字段,比如parcels.id } } } } } }
方式二:修改脚本直接访问_source(仅适用于_source未被禁用的情况)
调整脚本的_source访问方式,并增加空值判断:
{ "size": 0, "aggs": { "total_parcels": { "sum": { "script": { "source": "params._source.parcels != null ? params._source.parcels.length : 0" } } } } }
内容的提问来源于stack exchange,提问作者Ori Dar
相关产品推荐
相关产品推荐

