Jolt嵌套数组转换问题:保留Product字段并拆分feeRate
解决Jolt转换中多ProductCharge展开及字段保留问题
问题场景
现有两类JSON输入结构:
输入1(单个ProductCharge)
{ "Product": [ { "id": 123, "name": "foo", "ProductCharge": [ { "productCode": "PIIB", "configLevel": "PROD", "feeRate": [ { "rate": 123, "range": "123" }, { "rate": 321, "range": "321" } ] } ] } ] }
输入2(多个ProductCharge)
{ "Product": [ { "id": 123, "name": "foo", "ProductCharge": [ { "aboveAmount": 0, "chargeType": "ABC", "chargeValueType": "PERCENT", "frequency": 1, "feeRate": [ { "bandNumber": 1, "rate": 0.6 }, { "bandNumber": 2, "rate": 1.7 } ] }, { "aboveAmount": 0, "chargeType": "DEF", "chargeValueType": "PERCENT", "frequency": 1, "feeRate": [ { "bandNumber": 1, "rate": 0.75 }, { "bandNumber": 2, "rate": -0.55 } ] } ] } ] }
预期输出
需要将每个ProductCharge下的feeRate数组展开,每个feeRate对象与所属ProductCharge的其他字段合并,生成独立的ProductCharge对象,同时保留Product下的id、name等所有顶层字段。以输入2为例,预期输出为:
{ "Product" : [ { "id" : 123, "name" : "foo", "ProductCharge" : [ { "aboveAmount" : 0, "chargeType" : "ABC", "chargeValueType" : "PERCENT", "frequency" : 1, "bandNumber" : 1, "rate" : 0.6 }, { "aboveAmount" : 0, "chargeType" : "ABC", "chargeValueType" : "PERCENT", "frequency" : 1, "bandNumber" : 2, "rate" : 1.7 }, { "aboveAmount" : 0, "chargeType" : "DEF", "chargeValueType" : "PERCENT", "frequency" : 1, "bandNumber" : 1, "rate" : 0.75 }, { "aboveAmount" : 0, "chargeType" : "DEF", "chargeValueType" : "PERCENT", "frequency" : 1, "bandNumber" : 2, "rate" : -0.55 } ] } ] }
原方案问题
- 最初的Jolt Spec无法保留
Product下的id、name等字段; - 后续调整后,当存在多个
ProductCharge时,同位置的字段会被合并为数组,不符合预期。
修正后的Jolt转换规则
[ { "operation": "shift", "spec": { "Product": { "*": { // 保留Product下所有非ProductCharge的字段 "*": "Product[&1].&", "ProductCharge": { "*": { "feeRate": { "*": { // 用ProductCharge索引+feeRate索引作为唯一标识,避免字段合并 "@2,aboveAmount": "Product[#5].ProductCharge[#3_&1].aboveAmount", "@2,chargeType": "Product[#5].ProductCharge[#3_&1].chargeType", "@2,chargeValueType": "Product[#5].ProductCharge[#3_&1].chargeValueType", "@2,frequency": "Product[#5].ProductCharge[#3_&1].frequency", "@2,productCode": "Product[#5].ProductCharge[#3_&1].productCode", "@2,configLevel": "Product[#5].ProductCharge[#3_&1].configLevel", // 保留feeRate下的所有字段 "*": "Product[#5].ProductCharge[#3_&1].&" } } } } } } } }, { // 移除可能残留的feeRate字段(可选) "operation": "remove", "spec": { "Product": { "*": { "ProductCharge": { "*": { "feeRate": "" } } } } } } ]
规则说明
- 保留顶层字段:通过
"*": "Product[&1].&"直接映射Product下除ProductCharge外的所有字段,确保id、name不丢失。 - 避免字段合并:用
#3_&1作为新ProductCharge数组的索引(#3是外层ProductCharge的索引,&1是当前feeRate的索引),让每个ProductCharge+feeRate组合对应唯一位置,防止同名字段被合并为数组。 - 合并字段:通过
@2,字段名提取当前feeRate所属ProductCharge的字段,与feeRate字段合并到同一对象。 - 兼容多场景:规则同时覆盖了两类输入的字段,无需针对不同输入修改规则。
内容的提问来源于stack exchange,提问作者Mahesh Gopalan
相关产品推荐
相关产品推荐

