Jolt向map数组添加公共map元素避免同索引元素合并问题
Jolt向数组首位插入固定元素时字段合并问题解决
问题场景
使用Jolt进行JSON转换时,输入JSON中geo数组的每个元素都包含元素为map类型的locations数组,需求为向所有locations数组的首位插入固定公共map元素,公共map内容如下:
{ "city": "XYZ", "zip": "0000", "sublocations": [ "included" ] }
预期效果为公共map作为独立数组项,存在于每个locations数组的0索引位置。使用自行编写的shift类型Jolt spec执行转换后,0索引位置的公共map与原locations数组0索引位置的原有map发生同名字段合并,同名字段值被合并为数组类型,未得到预期的独立数组元素。
相关参考内容
输入JSON
{ "geo": [ { "locationCode": "USA", "locations": [ { "city": "AMS", "zip": "1234", "sublocations": [ "included" ] }, { "city": "EDF", "zip": "4567", "sublocations": [ "included" ] } ] }, { "locationCode": "FRN", "locations": [ { "city": "CVF", "zip": "4321", "sublocations": [ "included" ] }, { "city": "GHJ", "zip": "8901", "sublocations": [ "included" ] } ] } ] }
预期输出JSON
{ "geo": [ { "locationCode": "USA", "locations": [ { "city": "XYZ", "zip": "0000", "sublocations": [ "included" ] }, { "city": "AMS", "zip": "1234", "sublocations": [ "included" ] }, { "city": "EDF", "zip": "4567", "sublocations": [ "included" ] } ] }, { "locationCode": "FRN", "locations": [ { "city": "XYZ", "zip": "0000", "sublocations": [ "included" ] }, { "city": "CVF", "zip": "4321", "sublocations": [ "included" ] }, { "city": "GHJ", "zip": "8901", "sublocations": [ "included" ] } ] } ] }
原有错误Jolt Spec
[{ "operation": "shift", "spec": { "geo": { "*": { "locations": { "#XYZ": "geo[&2].locations[0].city", "#0000": "geo[&2].locations[0].zip", "#included": "geo[&2].locations[0].sublocations[]", "*": { "*": "geo[#4].locations[#2].&" } }, "*": "geo[#2].&" } } } }]
实际错误输出
{ "geo" : [ { "locationCode" : "USA", "locations" : [ { "city" : [ "XYZ", "AMS" ], "zip" : [ "0000", "1234" ], "sublocations" : [ "included", [ "included" ] ] }, { "city" : "EDF", "zip" : "4567", "sublocations" : [ "included" ] } ] }, { "locationCode" : "FRN", "locations" : [ { "city" : [ "XYZ", "CVF" ], "zip" : [ "0000", "4321" ], "sublocations" : [ "included", [ "included" ] ] }, { "city" : "GHJ", "zip" : "8901", "sublocations" : [ "included" ] } ] } ] }
问题根因
原有spec存在两处逻辑错误:
- 遍历原
locations数组元素时,直接使用#2获取原数组索引作为输出路径索引,原数组首个元素的索引为0,和硬编码写入公共元素的路径locations[0]完全重合。Jolt shift操作对相同路径下的同名字段会自动执行值合并,最终生成数组类型字段值,是公共元素和原首个元素被合并的核心原因。 - 公共元素的
sublocations字段赋值时使用了[]通配符,和原数组中本身为数组类型的sublocations写入逻辑叠加后,会出现数组嵌套的异常结构。
修正方案
将原locations数组的所有元素输出索引整体+1,把0号位置预留给固定公共元素即可,修正后的可直接使用的spec如下:
[ { "operation": "shift", "spec": { "geo": { "*": { "locations": { // 写入0位置的固定公共元素 "#XYZ": "geo[&2].locations[0].city", "#0000": "geo[&2].locations[0].zip", "#included": "geo[&2].locations[0].sublocations[0]", // 原数组元素索引+1,从位置1开始写入,避免和公共元素位置冲突 "*": { "*": "geo[#4].locations[#2+1].&" } }, // 其余非locations字段正常透传 "*": "geo[#2].&" } } } } ]
修正点说明
- 原
locations数组元素的输出路径索引从#2调整为#2+1,原索引0的元素会写入位置1,原索引1的元素写入位置2,不会和位置0的公共元素路径冲突,从根本上避免字段合并问题。 - 公共元素的
sublocations固定值直接写入[0]位置,解决数组嵌套问题。 - 其余字段透传逻辑保持不变,不影响原有其他字段的输出。
内容的提问来源于stack exchange,提问作者coder1234
相关产品推荐
相关产品推荐

