Jolt Transformation: Un-nest object of form "key":{"value":"xyz"} to "key":"value" - json

I need to unwrap JSON objects in order to reduce the nesting of input like
[
{
"key1": {
"value": "abc"
},
"key2": {
"value": "xyz"
}
},
{
"key1": {
"value": "123"
},
"key2": {
"value": "456"
}
}
]
Instead it can just map straight to the value without the unnecessary object nesting.
Input JSON
[
{
"typedValues": {
"key1": {
"value": "abc"
},
"key2": {
"value": "xyz"
}
}
},
{
"typedValues": {
"key1": {
"value": "123"
},
"key2": {
"value": "456"
}
}
}
]
My spec attempt
I was able to remove the "typedValues" wrapping but unable to achieve the key:value reduction.
[
{
"operation": "shift",
"spec": {
"*": {
"typedValues": {
"#": ""
}
}
}
}
]
Output from attempt
[
{
"key1": {
"value": "abc"
},
"key2": {
"value": "xyz"
}
},
{
"key1": {
"value": "123"
},
"key2": {
"value": "456"
}
}
]
Desired output
[
{
"key1": "abc",
"key2": "xyz"
},
{
"key1": "123",
"key2": "456"
}
]

You can use a shift transformaion such as
[
{
"operation": "shift",
"spec": {
"*": {
"*": {
"*": {
"value": "&3.&1" // &3 : going 3 levels up the tree to grab the outermost indexes of the wrapper objects
} // &1 : replicating key 1/2 after going 1 level up
}
}
}
},
{ // to get rid of the object keys
"operation": "shift",
"spec": {
"*": ""
}
}
]
or shorly match #value with & wildcard which represents the current level replication of the key values
[
{
"operation": "shift",
"spec": {
"*": {
"*": { //typedValues
"*": {
"#value": "[&3].&"
}
}
}
}
}
]

Related

JOLT JSON Transformation - Filter Array by Dynamic Attribute Value Not Working

The filtering of JSON array works fine if we specify a static search value. This does not work if we apply a dynamic value.
Tried by dynamically passing the value.
Added below the input json along with the jolt spec for your reference.
Input:
{
"selected_key": "key2",
"keys": [
{
"name": "value1",
"key": "key1"
},
{
"name": "value21",
"key": "key2"
},
{
"name": "value22",
"key": "key2"
},
{
"name": "value3",
"key": "key3"
},
{
"name": "value4",
"key": "key4"
}
]
}
JOLT Spec:
[
{
"operation": "shift",
"spec": {
"keys": {
"*": {
"key": {
"#(4,selected_key)": {
"#2": "test"
}
}
}
}
}
}
]
Expected Output:
{
"test": [
{
"name": "value21",
"key": "key2"
},
{
"name": "value22",
"key": "key2"
}
]
}
Output:
The spec is not filtering any value and all the array items are added to the output json
{
"test": [
{
"name": "value1",
"key": "key1"
},
{
"name": "value21",
"key": "key2"
},
{
"name": "value22",
"key": "key2"
},
{
"name": "value3",
"key": "key3"
},
{
"name": "value4",
"key": "key4"
}
]
}
You can use two consecutive shift transformation spec such as
[
{// tag the objects or array of objects by common "key" values
"operation": "shift",
"spec": {
"*": "&",
"keys": {
"*": {
"#": "#(1,key)"
}
}
}
},
{// rename "key2" with "test"
"operation": "shift",
"spec": {
"selected_key": {
"*": {
"#(2,&)": "test"
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

JOLT Keep structure after array shift

I'm trying to construct a JOLT transformation such that it will change a parameter value if the paramter name matches in a given array.
Example Input:
{
"component": {
"parameters": [
{
"parameter": {
"name": "var_name",
"value": "val"
}
},
{
"parameter": {
"name": "1",
"value": "2"
}
}
]
},
"additional": "onemore"
}
Desired Output:
{
"component": {
"parameters": [
{
"parameter": {
"name": "var_name",
"value": "new_val"
}
},
{
"parameter": {
"name": "1",
"value": "2"
}
}
]
},
"additional": "onemore"
}
My Current JOLT transform:
[
{
"operation": "shift",
"spec": {
"component": {
"parameters": {
"*": {
"parameter": {
"name": {
"var_name": {
"#new_val": "&6.&5[&4].&3.value"
}
}
}
}
}
}
}
}
]
The problem with my JOLT transform is that it deletes the rest of the Json, whereas I'd like to mantain it unchanged if there's no match
I tried looking for a solution, but the closest I got was this one, which allowed me to make the current transform, but I don't understand how to fix it properly.
EDIT:
I actually missed part of the input when writing the example, but thanks to #Barbaros Özhan answer I was able to complete my transformation.
For future rference if anybody else needs it my original input had additonal fields like:
{
"component": {
"parameters": [
{
"option": "true",
"parameter": {
"name": "var_name",
"description": "desc",
"value": "val"
}
},
{
"option": "false",
"parameter": {
"name": "1",
"description": "desc",
"value": "2"
}
}
],
"other value": "baz"
},
"additional": "onemore"
}
And the final transformation I used was slightly tweaked to account for those like so:
[
{
"operation": "shift",
"spec": {
"component": {
"parameters": {
"*": {
"parameter": {
"name": {
"#": "&5.&4[&3].&2.&1",
"var_name": {
"#new_val": "&6.&5[&4].&3.value"
},
"*": {
"#(2,value)": "&6.&5[&4].&3.value"
}
},
"value": "&6.&5[&4].&3.value",
"*": "&4.&3[&2].&1.&"
},
"*": "&3.&2[&1].&"
}
},
"*": "&1.&"
},
"*": "&"
}
}
]
You can use this shift transformation spec
[
{
"operation": "shift",
"spec": {
"component": {
"parameters": {
"*": {
"parameter": {
"name": {
"#": "&5.&4[&3].&2.&1", // # matches the value taken from one level up, eg. replicating "name"
"var_name": {
"#new_val": "&6.&5[&4].&3.value"
},
"*": {
"#(2,value)": "&6.&5[&4].&3.value"
}
}
}
}
}
},
"*": "&" // the "else" case(the attributes other than "component")
}
}
]

Jolt transformation array data

I want to transform a JSON using JOLT like this:
Input: {
"array": [
"1","2","3","4"
],
"array2": [
{
"something": "123",
"something1": "Plane"
},
{
"something3": "567",
"something4": "Car"
}
]
}
Into the following format, as you can see from output I need data from both arrays to fit exact param names, not empty one like in the first or existed param names like in the second one.
Output: {
"one_array": [
{
"code": "1",
"description": "",
},
{
"code": "2",
"description": "",
},
{
"code": "3",
"description": "",
},
{
"code": "4",
"description": "",
}
], "other_array": [
{
"id": "123",
"type": "Plane"
},
{
"id": "567",
"type": "Car"
}
]
}
Some clarifications are really appreciated
You can achieve this using 2 shift operations and the default operation as below.
[
{
"operation": "shift",
"spec": {
"array": {
"*": {
"#": "one_array[&].id"
}
},
"array2": {
"*": {
"*": {
"#": "tmp_array[&2]"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"one_array": "one_array",
"tmp_array": {
"*": {
"0": "other_array[&1].id",
"1": "other_array[&1].type"
}
}
}
},
{
"operation": "default",
"spec": {
"one_array[]": {
"*": {
"description": ""
}
}
}
}
]

Json array elements duplication using jolt

I want to know if jolt can handle the following transformation:
{
"interface": [
{
"field": "A",
"ip": [
"1.1.1.1",
"1.1.1.2"
]
},
{
"field": "B",
"ip": [
"1.1.1.3"
]
}
]
}
to
{
"interface": [
{
"field": "A",
"ip": "1.1.1.1"
},
{
"field": "A",
"ip": "1.1.1.2"
},
{
"field": "B",
"ip": "1.1.1.3"
}
]
}
i.e for a JSON array containing a child array, create one version of parent item for each of its child array item.
Can jolt do that?
This can be achieved by doing a two stage shift:
Create an array of arrays
Then flatten the array of arrays
[
{
"operation": "shift",
"spec": {
"interface": {
"*": {
"ip": {
"*": {
"#": "[&3].[&1].ip",
"#(2,field)": "[&3].[&1].field"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": "interface.[]"
}
}
}
]
It is not complete answer, but maybe that helps you somehow or someone else could help?
[
{
"operation": "shift",
"spec": {
"interface": {
"*": {
"ip": {
"*": {
"#": "ip",
"#(2,field)": "field"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"ip": {
"*": {
"#": "interface[&1].ip",
"#(2,field)": {
"???": "interface[&2].field" // How to take proper index of an array?
}
}
}
}
}
]

What should be exact Jolt Spec for optionList like following?

The requirement is to flatten the hierarchical list into single list as shown in output with key's value as KEY and value's value as VALUE in final list. (sample output added).
INPUT:
{
"optionList": [{
"key": "General",
"values": [{
"key": "A",
"value": ["a"]
},
{
"key": "B",
"value": ["b"]
},
{
"key": "C",
"value": ["c"]
}]
}]
}
Required Output :
{
"A":"a",
"B":"b",
"C":"c"
}
Below transformation should work for you:
[
{
"operation": "shift",
"spec": {
"optionList": {
"*": {
"values": {
"*": {
"value": "#(1,key)"
}
}
}
}
}
}, {
"operation": "cardinality",
"spec": {
"*": {
"#": "ONE"
}
}
}
]
See also:
Transpose data in an Array.
CardinalityTransform