I have a json like
{
"Product": [
{
"id": 123,
"name": "foo",
"ProductCharge": [
{
"productCode": "PIIB",
"configLevel": "PROD",
"feeRate": [
{
"rate": 123,
"range": "123"
},
{
"rate": 321,
"range": "321"
}
]
}
]
}
]
}
which I want transformed to this
{
"Product" : [ {
"id": 123,
"name": "foo",
// more fields
"ProductCharge" : [ {
"productCode" : "PIIB",
"configLevel" : "PROD",
"rate" : 123,
"range" : "123"
}, {
"productCode" : "PIIB",
"configLevel" : "PROD",
"rate" : 321,
"range" : "321"
} ]
} ]
}
I have this spec,
[
{
"operation": "shift",
"spec": {
"Product": {
"*": {
// Preserve the id, name, and any other top-level fields
"ProductCharge": {
"*": {
"feeRate": {
"*": {
"@2": { "*": "Product[#6].ProductCharge.[&1].&" },
"*": "Product[#6].ProductCharge.[&1].&"
}
}
}
}
}
}
}
},
{
"operation": "remove",
"spec": {
"Product": {
"*": {
"ProductCharge": {
"*": {
"feeRate": ""
}
}
}
}
}
}
]
My current spec is missing the "id" and "name" and the other fields under "Product". If I try to add this line to get the remaining fields under "Product", it distorts the whole structure
"*": "Product[#2].&"
Can someone point out how to get around this.
Edit:
Barbaros's your solution worked, but I realized when I have more than one ProductCharge like below
{
"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
}
]
}
]
}
]
}
rather than create it as 4 separate sections
{
"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
} ]
} ]
}
it creates like this;
{
"Product" : [ {
"id" : 123,
"name" : "foo",
"ProductCharge" : [ {
"aboveAmount" : [ 0, 0 ],
"chargeType" : [ "ABC", "DEF" ],
"chargeValueType" : [ "PERCENT", "PERCENT" ],
"frequency" : [ 1, 1 ],
"bandNumber" : [ 1, 1 ],
"rate" : [ 0.6, 0.75 ]
}, {
"aboveAmount" : [ 0, 0 ],
"chargeType" : [ "ABC", "DEF" ],
"chargeValueType" : [ "PERCENT", "PERCENT" ],
"frequency" : [ 1, 1 ],
"bandNumber" : [ 2, 2 ],
"rate" : [ 1.7, -0.55 ]
} ]
} ]
}
You can handle the issue better by accumulating the inner stuff( those within the "feeRate"
array ) in a new object, namely "Others"
while using placeholder ampersand symbols for the keys such as "Product", "ProductCharge" and "feeRate" such that
[
{
"operation": "shift",
"spec": {
"Product": {
"*": {
"*": "&2[&1].&",
"ProductCharge": {
"*": {
"*": "&4[&3].&2[&1].Others.&",
"feeRate": "&4[&3].&2[&1].&"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"Product": {
"*": {
"*": "&2[&1].&",
"ProductCharge": {
"*": {
"feeRate": {
"*": {
"@2,Others": { "*": "&7[&6].&5[&1].&" },
"*": "&6[&5].&4[&1].&"
}
}
}
}
}
}
}
}
]
the demo on the site Jolt Transform Demo Using v0.1.1 is :
Edit : You'll need to add one more partition for this new case and the expression &3_&1
will do the trick such as
[
{
"operation": "shift",
"spec": {
"Product": {
"*": {
"*": "&2.&",
"ProductCharge": {
"0": { //in order to bring only once among duplicated values
"*": "&4.&2.Others.&",
"feeRate": {
"*": {
"*": "&6.&4.&2.&3_&1.&"
}
}
},
"*": {
"feeRate": {
"*": {
"*": "&6.&4.&2.&3_&1.&"
}
}
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"Product": {
"*": "&1[0].&",
"ProductCharge": {
"feeRate": {
"*": {
"@": "&4[0].&3.[#2]",
"@2,Others": { "*": "&5[0].&4.[#3].&" }
}
}
}
}
}
}
]
This last spec will handle the previous case as well