JOLT转换:如何有条件合并两个字段并保留其他属性?
解决JOLT合并AccountNumber与EntityID时生成数组的问题
需求说明
需要合并AccountNumber和EntityID两个字段,仅保留非空值(输入保证二者必有一个有效,且绝不会同时有值),同时保留其他所有相关属性。
输入示例
{ "AccountNumber": "123456", "EntityID": "", "TransactionYear": "2023", "TransactionMonth": "03", "TransactionDay": "05", "TransactionHour": "10", "TransactionMinutes": "15", "TransactionSeconds": "30", "ComponentNumber": "12345", "Price": "250.00", "CurrencyCode": "USD" }
目标输出
合并后AccountNumber为单个非空值,保留其他所有属性:
{ "AccountNumber": "123456", "TransactionData": { "TransactionYear": "2023", "TransactionMonth": "03", "TransactionDay": "05", "TransactionHour": "10", "TransactionMinutes": "15", "TransactionSeconds": "30" }, "NewPrice": { "ComponentNumber": "12345", "SpecialPrice": { "Price": "250.00", "CurrencyCode": "USD" } } }
当前问题
原JOLT规范使用firstNotNull时,输出的AccountNumber是包含空字符串和有效值的数组,而非单个值:
{ "AccountNumber": ["","123456"], "TransactionData": { "TransactionYear": "2023", "TransactionMonth": "03", "TransactionDay": "05", "TransactionHour": "10", "TransactionMinutes": "15", "TransactionSeconds": "30" }, "NewPrice": { "ComponentNumber": "12345", "SpecialPrice": { "Price": "250.00", "CurrencyCode": "USD" } } }
解决方案
方案1:利用Shift操作的条件过滤(推荐)
直接在Shift步骤中添加非空判断,仅将非空字段映射到目标AccountNumber字段,无需额外临时字段和修改步骤:
[ { "operation": "shift", "spec": { // 仅当AccountNumber非空时映射到目标字段 "AccountNumber": { "?": { "@(2,AccountNumber)": "AccountNumber" } }, // 仅当EntityID非空时映射到目标字段(二者不同时有值,不会冲突) "EntityID": { "?": { "@(2,EntityID)": "AccountNumber" } }, "TransactionYear": "TransactionData.TransactionYear", "TransactionMonth": "TransactionData.TransactionMonth", "TransactionDay": "TransactionData.TransactionDay", "TransactionHour": "TransactionData.TransactionHour", "TransactionMinutes": "TransactionData.TransactionMinutes", "TransactionSeconds": "TransactionData.TransactionSeconds", "ComponentNumber": "NewPrice.ComponentNumber", "Price": "NewPrice.SpecialPrice.Price", "CurrencyCode": "NewPrice.SpecialPrice.CurrencyCode" } } ]
方案2:先将空字符串转为Null再使用firstNotNull
如果需要保留临时字段的方式,可先将空字符串转为null,让firstNotNull能正确识别并选择第一个非空值:
[ { "operation": "shift", "spec": { "AccountNumber": "Temp.AccountNumber", "EntityID": "Temp.EntityID", "TransactionYear": "TransactionData.TransactionYear", "TransactionMonth": "TransactionData.TransactionMonth", "TransactionDay": "TransactionData.TransactionDay", "TransactionHour": "TransactionData.TransactionHour", "TransactionMinutes": "TransactionData.TransactionMinutes", "TransactionSeconds": "TransactionData.TransactionSeconds", "ComponentNumber": "NewPrice.ComponentNumber", "Price": "NewPrice.SpecialPrice.Price", "CurrencyCode": "NewPrice.SpecialPrice.CurrencyCode" } }, { "operation": "modify-overwrite-beta", "spec": { "Temp": { // 将空字符串转为null,使firstNotNull能正确筛选 "AccountNumber": ["=isNull(@(1))", "@(1)"], "EntityID": ["=isNull(@(1))", "@(1)"] }, "AccountNumber": "=firstNotNull(@(1,Temp.AccountNumber), @(1,Temp.EntityID))" } }, { "operation": "remove", "spec": { "Temp": "" } } ]
问题原因说明
原规范中firstNotNull生成数组的核心原因是:JOLT将空字符串视为有效值,而非null。当传入两个参数(一个空字符串、一个有效值)时,firstNotNull不会筛选掉空字符串,而是将两个参数打包成数组返回。
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

