Json transformation from key value to nested array - json

I was trying to have a key value pair mapped to an array, distinguishing each value as a type using jolt transform spec
Input json
{
"testurl": "someurl",
"website": "someurl2"
}
tried this spec
[
{
"operation": "shift",
"spec": {
"testurl": "Urls[].testurl",
"website": "Urls[].website"
}
},
{
"operation": "shift",
"spec": {
"Urls": {
"*": {
"$": "Urls[&1].val"
}
}
}
}
]
Expected result is like this
{
"Urls": [{
"url": "someurl",
"val": "testurl"
}, {
"url": "someurl2",
"val": "website"
}]
}

Yes you can turn a set of Json key,value pair into an array.
It requires 2 shifts to be safe.
1st shift isolates all the properties you want to turn into an array.
2nd shift is able to use a "*" to then match all those items and place them an array.
Spec
[
{
"operation": "shift",
"spec": {
"testurl": "temp.testurl",
"website": "temp.website"
}
},
{
"operation": "shift",
"spec": {
"temp": {
"*": {
"$": "Urls[#2].val",
"#": "Urls[#2].url"
}
}
}
}
]

Related

Pull elements out of two arrays to make a "flat" item list

I need to merge array data from two different arrays from the Input JSON and make a flat list of items in the Output JSON. The first array contains the key required for the output and the second array contains the value.
So far, all my attempts at a spec haven't even come close, which is why I haven't listed one. Please see the Input and Desired Output below. Thanks for any help!!
Input JSON :
{
"data": [
{
"2": {
"value": "DC1"
},
"3": {
"value": 5
}
},
{
"2": {
"value": "DC2"
},
"3": {
"value": 10
}
}
],
"fields": [
{
"id": 2,
"label": "DataCenter",
"type": "text"
},
{
"id": 3,
"label": "CCount",
"type": "numeric"
}
],
"metadata": {
"numFields": 2,
"numRecords": 2,
"skip": 0,
"totalRecords": 2
}
}
Desired Output JSON:
[
{
"DataCenter": "DC1",
"CCount": "5"
},
{
"DataCenter": "DC2",
"CCount": "10"
}
]
You can use this spec:
[
{
"operation": "shift",
"spec": {
"data": "&",
"fields": {
"*": {
"label": "fields.#(1,id)"
}
}
}
},
{
"operation": "shift",
"spec": {
"data": {
"*": {
"*": {
"*": "[&2].#(4,fields.&1)"
}
}
}
}
}
]
In your desired output CCount value is a string, You can add the below spec to change an integer to a string.
,
{
"operation": "modify-overwrite-beta",
"spec": {
"*": {
"CCount": "=toString"
}
}
}
You might reciprocally match id value of fields array vs. the object keys of the data array within a common object within the first shift transformation spec in order to prepare for the second one in which we tile the attributes into their individual objects such as
[
{
"operation": "shift",
"spec": {
"*": { // represents the node for both "data" and "fields" arrays
"*": {
"*": {
"value": "&1.&",
"#1,label": "#2,id.&"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"value": {
"*": "[&].#2,label"
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

How to split the nested JSON in Jolt specification

pls help me out wit this jolt specification. pls help me
Notes :
Resourcename is the last element of ResourceId which will be a new attribute that we need to add to the expected output
Tags field needs to be copied and splited as mentioned in the expected output.
Input :
[
{
"ResourceId": "/subscriptions/bb842437aa4/resourceGroups/ECHLABHENKEL/providers/Microsoft.Compute/virtualMachines/pmoapps",
"Tags": "Name\": \"PMOapplication\",\"Owner\": \"Breil sathish"
},
{
"ResourceId": "/subscriptions/bb842437aa4/resourceGroups/HCLTECHLABHENKEL/providers/Microsoft.Compute/virtualMachines/pmoapps",
"Tags": "Name\": \"PMOapplication\",\"Owner\": \"Breil sathish1"
}
]
Expected Output :
[
{
"ResourceId": "/subscriptions/bb842437aa4/resourceGroups/ECHLABHENKEL/providers/Microsoft.Compute/virtualMachines/pmoapps",
"Tags": "Name\": \"PMOapplication\",\"Owner\": \"Breil sathish",
"Resourcename": "pmoapps",
"Name": "PMOapplication",
"Owner": "Breil sathish"
},
{
"ResourceId": "/subscriptions/bb842437aa4/resourceGroups/HCLTECHLABHENKEL/providers/Microsoft.Compute/virtualMachines/pmoapps",
"Tags": "Name\": \"PMOapplication\",\"Owner\": \"Breil sathish1",
"Resourcename": "pmoapps",
"Name": "PMOapplication",
"Owner": "Breil sathish1"
}
]
Thanks,
N Sathish
You can use the following transformation spec as reading the explanations stated at the beginning of each of them such as
[
{ // Convert the value of the attributes to individual arrays with the identical names
"operation": "modify-overwrite-beta",
"spec": {
"*": {
"ResourceName": "=split('/', #(1,ResourceId))",
"tag": "=split(',', #(1,Tags))"
}
}
},
{ // Generate tag0 and tag1 attributes by splitting members of the "tag" array
"operation": "shift",
"spec": {
"*": {
"*": "&1.&",
"tag": {
"*": {
"#": "&3.&2&1"
}
}
}
}
},
{ // Split related strings by colon characters for "tag" array while deriving the last element of "ResourceName" array
"operation": "modify-overwrite-beta",
"spec": {
"*": {
"R*": "=lastElement(#(1,&))",
"tag*": "=split(': ', #(1,&))"
}
}
},
{ // Match components of "tag" array component 1 against component 2
"operation": "shift",
"spec": {
"*": {
"*": "&1.&",
"tag*": {
"#1,&[1]": "&2.&1.#(2,&[0])"
}
}
}
},
{ // Split the values by \" character combination
"operation": "modify-overwrite-beta",
"spec": {
"*": {
"tag*": {
"*": "=split('\"', #(1,&))"
}
}
}
},
{ // Prune undesired values for right-hand-side
"operation": "modify-overwrite-beta",
"spec": {
"*": {
"tag*": {
"*": "=join('', #(1,&))"
}
}
}
},
{ // Prune undesired values for left-hand-side(keys)
"operation": "shift",
"spec": {
"*": {
"*": "[&1].&",
"tag*": {
"\"*\"": "[&2].&(0,1)",
"*\"": "[&2].&(0,1)"
}
}
}
}
]

JOLT JSON transform values from one-to-many to one-to-one

I'm trying to map one key to each value in array to a new array by using JOLT.
Could someone please help give me a solution for this:
My JSON:
[
{
"person_id": "1",
"resources": ["asd", "zxc"]
},
{
"person_id": "2",
"resources": ["ghj", "asd"]
}
]
And my expected JSON:
[
{
"person_id": "1",
"resource": "asd"
},
{
"person_id": "1",
"resource": "zxc"
},
{
"person_id": "2",
"resource": "ghj"
},
{
"person_id": "2",
"resource": "asd"
}
]
I had tried this Jolt Specification
[
{
"operation": "shift",
"spec": {
"*": {
"resources": {
"*": {
"#(2,person_id)": "[&].person_id",
"#": "[&].resource"
}
}
}
}
}
]
But no luck it always maps all values at the same index to 1 array.
You can use two consecutive shift transformation specs by walking through the resources array within the first one such that
[
{
"operation": "shift",
"spec": {
"*": {
"*s": { // this tecnique stands for extracting by the replacement of the asterisk through use of &(2,1) below
"*": {
"#(2,person_id)": "[&3].&1.person_id", // to separate by indexes of the array to generate three level for three independent objects
"#": "[&3].&1.&(2,1)"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": ""
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is
You can use this jolt spec:
[
{
"operation": "shift",
"spec": {
"*": {
"*s": {
"*": {
"#(2,person_id)": "#(1).person_id",
"#": "#(1).&(2,1)"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": ""
}
}
]

Jolt Transform filter values using another value of the json

I have this JSON:
{
"mapTrue": "true",
"code": [
"X",
"Y",
"Z"
],
"expired": [
"true",
"false",
"true"
]
}
I want to use the "mapTrue" value in order to filter the "code" array.
If "mapTrue": "true", I'll take the 0 and 2 values in "expired" array, therefore I need to output
"code": ["X", "Z"].
Using the same logic, for "mapTrue: "false" I'll return "code": ["Y"].
This specification returns the right "code" array but it doesn't use the "mapTrue" value.
[
{
"operation": "shift",
"spec": {
"expired": {
"*": {
"true": {
"#(3,code[&1])": "code"
}
}
}
}
}
]
That's where my problem is.
This works:
[
{
"operation": "shift",
"spec": {
"expired": "#(1,mapTrue)",
"code": "code"
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": {
"&1": {
"#(3,code[&1])": "code[]"
}
}
}
}
}
]
An alternative option would be using the following specs
[
{
// separate the values for "true", "false" while match "code" with the value of "mapTrue"
"operation": "shift",
"spec": {
"c*": {
"*": "#(2,expired[&])", // walk through the indexes(0,1,2) of "expired" array while matching with the components of "code"
"#(1,mapTrue)": "&1"
}
}
},
{
"operation": "shift",
"spec": {
"c*": {
"*": {
"#(2,&)": "&2" // grab the value going tree up two levels by using "#(2,&)", and copy the main object's label "code" by grabbing it after going tree two levels again
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

JOLT transformation filter a list about the first string element

I would like to search a list for the first real string element (which could be not a number) and output this.
Input :
{
"firstString": [
"0.20",
"test",
"0.30"
]
}
or
{
"firstString": [
"0.20",
"0,30",
"test"
]
}
Expected Output :
{
"readingS": "test"
}
The order of the element can change, either it comes to 2nd or 3rd placeholder. The list is maximum 3 elements long.
My thought was to go over either the last or middle element, however this does not work. The list is generated just before with the modify-overwrite-beta.
You can still use modify-overwrite-beta transformation along with toInteger conversion such as
[
//Determine the elements whether toInteger conversion is applicable for them
{
"operation": "modify-overwrite-beta",
"spec": {
"arr": "=(#(1,firstString))",
"0": "=toInteger(#(1,arr[0]))",
"1": "=toInteger(#(1,arr[1]))",
"2": "=toInteger(#(1,arr[2]))"
}
},
//The arrays are generated from the elements which are eligible to
//conversion, while not for the others
{
"operation": "shift",
"spec": {
"*": "&",
"arr": { "*": "&" }
}
},
//The arrays are removed, so all numeric ones by reversing
//key-value pairs
{
"operation": "shift",
"spec": {
"*": {
"$": "#(0)"
}
}
},
//Reverse back the pairs
{
"operation": "shift",
"spec": {
"*": {
"$": "readingS[#2]"
}
}
},
//and pick the leftmost element
{
"operation": "cardinality",
"spec": {
"*": "ONE"
}
}
]
You have some values that ended with numbers. So we can match all values that ended with the number, and we have a real string in the last.
[
{
"operation": "shift",
"spec": {
"firstString": {
"*": {
"*0": "",
"*1": "",
"*2": "",
"*3": "",
"*4": "",
"*5": "",
"*6": "",
"*7": "",
"*8": "",
"*9": "",
"*": {
"$": "readingS"
}
}
}
}
}, {
"operation": "shift",
"spec": {
"*": {
"*": "&"
}
}
}
]