Closed mordfustang00 closed 7 months ago
Hello,
The trick is to use operation shift.
[
{
"operation": "shift",
"spec": {
"CarStats": {
"odo": {
"unit": {
"3": { // value => mileValue
"@(2,value)": "CarStats.odo.mileValue",
"#1": "CarStats.odo.unit"
},
"1": { // value => kmValue
"@(2,value)": "CarStats.odo.kmValue",
"@1": "CarStats.odo.unit"
},
"*": { // do nothing
"@(2,value)": "CarStats.odo.value",
"@1": "CarStats.odo.unit"
}
}
}
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"CarStats": {
"*": {
"unit": "=toInteger",
"mileValue": "=divide(@0,0.621371)"
}
}
}
},
{
"operation": "shift",
"spec": {
"CarStats": {
"odo": {
"*": "&2.&1.&",
"kmValue|mileValue": "&2.&1.value"
}
}
}
}
]
thanks @gbouget it works, but i have another question. if my sample json data has data underneath, how i can display it in the output e.g.:
{ "CarStats": { "odo": { "value": 2000, "unit": 3 }, "fuel": { "value": "100%" }, "battery": { "percentage": "70%" } } }
With wildcard '*' in LHS (left part) and '&' in RHS (right part).
[
{
"operation": "shift",
"spec": {
"CarStats": {
"*": "&1.&", // except 'odo', all attributes will be mapped to &1.& (&1 = one level above, i.e. CarStats) (& = current value of *)
"odo": { // only matches 'odo'
"unit": {
"3": { // value => mileValue
"@(2,value)": "CarStats.odo.mileValue",
"#1": "CarStats.odo.unit"
},
"1": { // value => kmValue
"@(2,value)": "CarStats.odo.kmValue",
"@1": "CarStats.odo.unit"
},
"*": { // do nothing
"@(2,value)": "CarStats.odo.value",
"@1": "CarStats.odo.unit"
}
}
}
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"CarStats": {
"*": {
"unit": "=toInteger",
"mileValue": "=divide(@0,0.621371)"
}
}
}
},
{
"operation": "shift",
"spec": {
"CarStats": {
"*": "&1.&",
"odo": {
"*": "&2.&1.&",
"kmValue|mileValue": "&2.&1.value"
}
}
}
}
]
thanks for this. I noticed that the result has much decimal places. How can we limit up to 2 places only?
"mileValue": "=divideAndRound(2,@0,0.621371)" // round to 2 decimal places
thanks :)
@gbouget i have another question. i'm trying on the following input below (im trying for evRange at least, but trying also for totalAvailrange and gasRange)
Input: { "CarStats": { "odo": { "value": 7363.7, "unit": 3 }, "VehicleStats": { "evStats": { "Distance": [ { "type": 1, "FuelRange": { "evRange": { "value": 138, "unit": 3 }, "totalAvailRange": { "value": 138, "unit": 3 }, "gasRange": { "value": 0, "unit": 3 } } } ], "batteryStats": 75 } } } }
but i have this error (i think it has something to do with [ ] spec formatting: Error running the Transform.
JOLT Chainr encountered an exception constructing Transform className:com.bazaarvoice.jolt.Shiftr at index:0.
Invalid spec, RHS should be a String or array of Strings. Value in question : {FuelRange={evRange={unit={3={@(2,value)=CarStats.VehicleStats.evStats.Distance.FuelRange.evRange.evmileValue, #1=CarStats.VehicleStats.evStats.Distance.FuelRange.evRange.unit}, 1={@(2,value)=CarStats.VehicleStats.evStats.Distance.FuelRange.evRange.evkmValue, @1=CarStats.VehicleStats.evStats.Distance.FuelRange.evRange.unit}, *={@(2,value)=CarStats.VehicleStats.evStats.Distance.FuelRange.evRange.value, @1=CarStats.VehicleStats.evStats.Distance.FuelRange.evRange.unit}}}}}
this is the specs:
[ { "operation": "shift", "spec": { "CarStats": { "": "&1.&", // except 'odo', all attributes will be mapped to &1.& (&1 = one level above, i.e. CarStats) (& = current value of ) "odo": { // only matches 'odo' "unit": { "3": { // value => mileValue "@(2,value)": "CarStats.odo.mileValue", "#1": "CarStats.odo.unit" }, "1": { // value => kmValue "@(2,value)": "CarStats.odo.kmValue", "@1": "CarStats.odo.unit" }, "": { // do nothing "@(2,value)": "CarStats.odo.value", "@1": "CarStats.odo.unit" } } }, "VehicleStats": { "evStats": { "Distance": [ { "FuelRange": { "evRange": { "unit": { "3": { // value => mileValue "@(2,value)": "CarStats.VehicleStats.evStats.Distance.FuelRange.evRange.evmileValue", "#1": "CarStats.VehicleStats.evStats.Distance.FuelRange.evRange.unit" }, "1": { // value => kmValue "@(2,value)": "CarStats.VehicleStats.evStats.Distance.FuelRange.evRange.evkmValue", "@1": "CarStats.VehicleStats.evStats.Distance.FuelRange.evRange.unit" }, "": { // do nothing "@(2,value)": "CarStats.VehicleStats.evStats.Distance.FuelRange.evRange.value", "@1": "CarStats.VehicleStats.evStats.Distance.FuelRange.evRange.unit" } } } } } ] } } } } }, { "operation": "modify-overwrite-beta", "spec": { "CarStats": { "": { "unit": "=toInteger", "mileValue": "=divideAndRound(2,@0,0.621371)" } }, "VehicleStats": { "evStats": { "Distance": [ { "FuelRange": { "evRange": { "unit": "=toInteger", "evmileValue": "=divideAndRound(2,@0,0.621371)" } } } ] } } } }, { "operation": "shift", "spec": { "CarStats": { "": "&1.&", "odo": { "": "&2.&1.&", "kmValue|mileValue": "&2.&1.value" }, "VehicleStats": { "evStats": { "Distance": [ { "FuelRange": { "evRange": { "": "&2.&1.&", "evkmValue|evmileValue": "&2.&1.value" } } } ] } } } } } ]
To iterate an array with jolt, use:
"key": {
"*": {
// ...
}
}
instead of:
"key": [
//...
]
Example
thanks :)
Good day. I'm new to JOLT and i would like to ask on how we can add conditions for modify-overwrite-beta spec.
Here is my sample JSON input:
{ "CarStats": { "odo": { "value": 2000, "unit": 3 (given this is miles value) } }
I want to have this output:
{ "CarStats": { "odo": { "value": 3218.688, "unit": 1 (this is km value) } }
The criteria incase if the unit is 3, i will update value to 1, while at the same time it will calculate the value from miles to km otherwise, the value is as is.
Thanks :)