JOLT transformation for nested JSON? - json

I have a JSON that looks like this :
{
"Level1": {
"Level2": {
"val1": "Test",
"val2": "Val"
}
}
}
When I apply the followng Jolt shift transformation to this :
[{
"operation": "shift",
"spec": {
"Level1": {
"Level2": {
"val1": "val001",
"val2": "val002"
}
}
}
}]
I get the folliwng result :
{
"val001": "Test",
"val002": "Val"
}
Why cant I see the Level1, Level2 in the output? Please an someone help, I want to see that in the output too similar to whats the input.

The values in the shift spec usually refer to the location of the key in the output, so you'd need to include Level1 and Level2 in the values:
[{
"operation": "shift",
"spec": {
"Level1": {
"Level2": {
"val1": "Level1.Level2.val001",
"val2": "Level1.Level2.val002"
}
}
}
}]
If Level1 and/or Level2 can be arbitrary, you can use the # operator to "go back up the tree" and get the values (see the Shiftr javadoc for examples).

Related

unable to convert json list to objects using jolt

I need to use jolt transform to do the below JSON transformation.
need to create new columns from the list from reeval column where sometimes we only one value and some times we get multiple values my input data :-
example 1:
{
"id":"1",
"reeval":["one","two"]
}
example 2:
{
"id":"2",
"reeval":["one","two","three"]
}
example 3:
{
"id":"3",
"reeval":["one"]
}
I have written jolt expresson as below
[
{
"operation": "shift",
"spec": {
"id": "id",
"reeval": {
"*": "&"
}
}
}
]
with above jolt expression is working fine but unable to add column name
output for above jolt is as below
example 1:
{
"id" : "1",
"0" : "one",
"1" : "two"
}
example 2:
{
"id" : "2",
"0" : "one",
"1" : "two",
"2" : "three"
}
here i am unable to change the names of the columns as i need to change colunms as below
my expected output after jolt transformation should be like
example 1:
{
"id":"1",
"reeval":"one",
"reeval1":"two"
}
example 2:
{
"id":"2",
"reeval":"one",
"reeval1":"two",
"reeval2":"three"
}
example 3:
{
"id":"3",
"reeval":"one"
}
Prepending &1 to the current ampersand would suffice in order to go one level up the tree, and to grab the key name in the first shift transformation, and then apply another to rename only the key with index zero such as
[
{
"operation": "shift",
"spec": {
"id": "id",
"reeval": {
"*": "&1&"
}
}
},
{
"operation": "shift",
"spec": {
"reeval0": "reeval",
"*": "&"
}
}
]

Converting List to Comma Separated String in JOLT

I have below scenario, where two operations need to be performed. One is parsing the list and create a comma separated string. Then, transform that into the output format json
Input -
{
"list": ["ABC","XYZ"]
}
Output -
{
"additionalAttributes" : {
"userContext" : [ {
"auths" : "ABC,XYZ"
} ]
}
}
Check this spec
[
{
"operation": "modify-overwrite-beta",
"spec": {
"list": "=join(',',#(1,list))"
}
}, {
"operation": "shift",
"spec": {
"list": "additionalAttributes.userContext[].auths"
}
}
]

Jolt transform so that data of an element is the key and the value is another elements data

I need to perform a Jolt transformation on the below example json:
[ {
"name" : "foo",
"dataSample" : "red"
}, {
"name" : "bar",
"dataSample" : "amber"
}]
I need the output to look like:
{
"foo": "red",
"bar": "amber"
}
so far i've managed to extract the name value as the key, but i'm lost as to how to get the dataSample value as the value for the transformed element. Here's the Jolt script I have so far:
[
{
"operation" : "shift",
"spec" : {
"*" : {
"name" : {
"*" : "&"
}
}
}
}
]
You need to go back up the tree to get the value of the "name" field, rather than using the current value (&). This should work:
[
{
"operation": "shift",
"spec": {
"*": {
"name": {
"#(1,dataSample)": "#(2,name)"
}
}
}
}
]
[
{
"operation": "shift",
"spec": {
"*": {
"dataSample": "#(1,name)"
}
}
}
]

Jolt Transformation

I am trying to write a jolt transformation for below input -
{
"restaurantId": "ZZ4ORJDY3E",
"chainId": "a-b"
}
expected output is -
{
"ZZ4ORJDY3E" : {
"key" : "ZZ4ORJDY3E",
"start" : "a",
"end" : "b"
}
}
My spec is -
[
{
"operation": "shift",
"spec": {
"#restaurantId": "#restaurantId.key",
"chainId": {
"*-*": {
"$(0,1)": "#restaurantId.start",
"$(0,2)": "#restaurantId.end"
}
}
}
}
]
The spec is not transforming as expected output. i want learn how to use attributes inside string parser.
Spec
[
{
"operation": "shift",
"spec": {
"restaurantId": {
// match any value of restaurantId
"*": {
// write the value to of the key $ to the output
// where the output is the "value of the key".key
// kinda hokey
"$": "&.key"
}
},
"chainId": {
"*-*": {
// write each part of the chainId to the output
// at the value of restaurantId from back up the tree
"$(0,1)": "#(3,restaurantId).start",
"$(0,2)": "#(3,restaurantId).end"
}
}
}
}
]

How tracnform rest of json into one field value using jolt?

Here is the JSON input:
{
"myRootKey": {
"directMove": "directValue",
"marker": "THE_MARKER",
"someTextField": "someString",
"someObject": {
"someKey": "value"
}
}
}
the output should be:
{
"myRootKey": {
"subKey": {
"directMove": "directValue"
},
"THE_MARKER": {
"someTextField": "someString",
"someObject": {
"someKey": "value"
}
}
}
}
With direct moving it is clear, but how rest of the input to the marker object value?
You match down to "someTextField" and "someObject", but use the new "#" / look up the tree logic to find the "marker" to use as an ouput path.
Spec
[
{
"operation": "shift",
"spec": {
"myRootKey": {
"directMove": "myRootKey.subKey.directValue",
"someTextField": "#(1,marker).someTextField",
"someObject": "#(1,marker).someObject"
}
}
}
]
#(1,marker) allows you to retrieve the value of the marker field
&1 retrieves the value of the matching node
So the spec you are looking for looks like :
[
{
"operation": "shift",
"spec": {
"myRootKey": {
"directMove": "myRootKey.subKey.directValue",
"someTextField": "&1.#(1,marker).someTextField",
"someObject": "&1.#(1,marker).someObject"
}
}
}
]
You can use this spec fully dynamically:
[
{
"operation": "shift",
"spec": {
"*": {
"directMove": "&1.subKey.&",
"*TextField": "&1.#(1,marker).&",
"*Object": "&1.#(1,marker).&"
}
}
}
]