JSONata在新分组对象非首属性调用函数时触发栈溢出错误
JSONata 2.0.0多属性日期求和栈溢出递归问题排查
问题场景
你的数据结构大致如下(修正为标准JSON格式):
{ "property1": { "subProperty1": [{"date": "2022-01-01", "value": 10}, ...], "subProperty2": [{"date": "2022-01-01", "value": 50}, ...] } }
需求是按日期聚合所有子数组的value求和,但在JSONata 2.0.0中执行查询时出现栈溢出递归错误——首属性调用函数正常,后续属性完全失效;切换到1.8.6版本后问题消失。
可能的原因
2.0.0版本遍历逻辑变更
JSONata 2.0.0对通配符($.*)的递归遍历机制做了调整,当多层嵌套遍历与聚合函数(比如$sum)结合时,容易触发无限递归。比如使用$.*.*.*这种模糊多层遍历,2.0版本的上下文解析会反复回溯遍历路径,导致栈溢出。上下文引用冲突
如果你的查询中没有明确限定聚合逻辑的上下文范围,比如直接用value而非$item.value,2.0版本的上下文解析规则会将value误解析为当前正在构建的聚合对象的属性,形成循环引用,进而触发递归。空值过滤的位置错误
你用[value != null]过滤空值,但如果把过滤条件写在遍历层级之外,2.0版本的$sum函数会反复触发过滤逻辑,导致遍历过程中不断递归调用过滤表达式。
解决思路
- 明确限定遍历范围
放弃模糊的多层通配符,明确指定遍历层级,先扁平化所有子数组,再分组求和:
$group( $flatten($$.property1.*), $item.$item.date, $group.{ date: $group.key, total: $sum($group.*.value) } )
避免上下文泄漏
在聚合逻辑中严格限定引用范围,比如用$item.value而非直接value,确保只遍历原始数据项,不会误引用正在构建的结果。调整空值过滤位置
把空值过滤嵌入扁平化步骤,只处理有效数据:
$group( $flatten($$.property1.*[value != null]), $item.$item.date, $group.{ date: $group.key, total: $sum($group.*.value) } )
- 升级版本修复bug
JSONata 2.0.0可能存在嵌套遍历与聚合组合的已知bug,尝试升级到2.0.0之后的小版本(如2.0.1),很多此类递归问题已被修复。
内容的提问来源于stack exchange,提问作者Jesse Benjamin Slomowitz
相关产品推荐
相关产品推荐

