基于Jolt库处理多数组嵌套循环:我的转换Spec为何失效?
Jolt转换Spec问题分析与修正
问题背景
需要将包含人员列表的JSON按合同角色分组:
- 订阅者(SOUSCRIPTEUR)归入
policies.subscribers[] - 被保险人(ASSURE)归入
policies.insured[] - 共同订阅者(CO_SOUSCRIPTEUR)归入
policies.cosubscribers[]
同时生成parties列表和tickets.processId(根据订阅者是否为自然人设置%phys%或%morale%)。当前的Jolt Shift Spec无法得到预期输出,以下是问题分析和修正方案。
输入JSON
{ "personnes": [ { "refExternePersonne": "BGHT34271", "isPersonnePhysique": true, "rolesContrat": [ "CO_SOUSCRIPTEUR", "ASSURE" ], "adresses": [ { "typeAdresse": "RESIDENCE_SECONDAIRE" }, { "typeAdresse": "FISCALE" } ] }, { "refExternePersonne": "BGHT34272", "isPersonnePhysique": false, "rolesContrat": [ "SOUSCRIPTEUR", "PAYEUR_PRIMES", "ASSURE" ], "adresses": [ { "typeAdresse": "FISCALE" }, { "typeAdresse": "CORRESPONDANCE" } ] } ] }
当前Jolt Spec
[ { "operation": "shift", "spec": { "personnes": { "*": { "refExternePersonne": "parties[&1].partyRef", "rolesContrat": { "*": { "SOUSCRIPTEUR": { "@(3,isPersonnePhysique)": { "true": { "#%phys%": "tickets.processId" }, "false": { "#%morale%": "tickets.processId" } }, "@(3,refExternePersonne)": "policies.subscribers[].partyRef", "@(3,idPersonne)": "policies.subscribers[].partyId", "@(3,adresses)": "policies.subscribers[].addressesTemp" }, "CO_SOUSCRIPTEUR": { "@(3,refExternePersonne)": "policies.cosubscribers[].partyRef", "@(3,idPersonne)": "policies.cosubscribers[].partyId", "@(3,adresses)": "policies.cosubscribers[].addressesTemp" }, "ASSURE": { "@(3,refExternePersonne)": "policies.insured[].partyRef", "@(3,idPersonne)": "policies.insured[].partyId", "@(3,adresses)": "policies.insured[].addressesTemp" } } } } } } } ]
预期输出
{ "parties": [ { "partyRef": "BGHT34271" }, { "partyRef": "BGHT34272" } ], "policies": { "cosubscribers": [ { "partyRef": "BGHT34271", "addressesTemp": [ { "typeAdresse": "RESIDENCE_SECONDAIRE" }, { "typeAdresse": "FISCALE" } ] } ], "insured": [ { "partyRef": "BGHT34271", "addressesTemp": [ { "typeAdresse": "RESIDENCE_SECONDAIRE" }, { "typeAdresse": "FISCALE" } ] }, { "partyRef": "BGHT34272", "addressesTemp": [ { "typeAdresse": "FISCALE" }, { "typeAdresse": "CORRESPONDANCE" } ] } ], "subscribers": [ { "partyRef": "BGHT34272", "addressesTemp": [ { "typeAdresse": "FISCALE" }, { "typeAdresse": "CORRESPONDANCE" } ] } ] }, "tickets": { "processId": "%morale%" } }
当前Spec存在的问题
属性拆分导致数组对象异常
遍历rolesContrat数组时,每个属性(partyRef、addressesTemp)单独使用[]写入数组,会生成多个独立对象(比如一个对象只有partyRef,另一个只有addressesTemp),而不是将所有属性合并到同一个对象中。无效字段冗余
输入JSON中不存在idPersonne字段,但当前Spec仍尝试映射该字段,会生成无用的null值或空字段。tickets.processId赋值逻辑缺陷
嵌套在SOUSCRIPTEUR角色的遍历逻辑中,若存在多个订阅者,后续值会覆盖之前的赋值;同时遍历数组时可能触发多次赋值,最终结果取决于最后一次遍历的值。角色匹配时的数组索引问题
未确保同一人员的属性被写入同一个数组元素,逻辑上存在重复生成对象的隐患。
修正后的Jolt Spec
[ { "operation": "shift", "spec": { "personnes": { "*": { // 生成parties列表 "refExternePersonne": "parties[&1].partyRef", // 处理订阅者的processId:基于订阅者身份设置值 "rolesContrat": { "*": { "SOUSCRIPTEUR": { "@(2,isPersonnePhysique)": { "true": { "#%phys%": "tickets.processId" }, "false": { "#%morale%": "tickets.processId" } } } } }, // 根据角色分组,将当前人员的属性映射到对应数组的同一个对象中 "@": { "rolesContrat": { "SOUSCRIPTEUR": { "@2,refExternePersonne": "policies.subscribers[-1].partyRef", "@2,adresses": "policies.subscribers[-1].addressesTemp" }, "CO_SOUSCRIPTEUR": { "@2,refExternePersonne": "policies.cosubscribers[-1].partyRef", "@2,adresses": "policies.cosubscribers[-1].addressesTemp" }, "ASSURE": { "@2,refExternePersonne": "policies.insured[-1].partyRef", "@2,adresses": "policies.insured[-1].addressesTemp" } } } } } } } ]
修正说明
- 使用
@引用当前人员对象,结合角色匹配,将partyRef和addressesTemp写入同一个数组元素([-1]表示追加到数组末尾的当前元素),确保属性合并为一个对象。 - 移除了无效的
idPersonne映射,符合预期输出要求。 - 调整
tickets.processId的赋值逻辑,确保基于订阅者的身份正确设置值,避免多次覆盖的问题。 - 保留原
parties列表的生成逻辑,该逻辑本身是正确的。
内容的提问来源于stack exchange,提问作者gbouget
相关产品推荐
相关产品推荐

