Jolt : Add key in sub object - jolt

Input
{
"id": 1,
"name": "Sample name",
"attributes": {
"age": 10
}
}
Output
{
"id": 1,
"attributes": {
"name": "Sample name",
"age": 10
}
}
I want to carry out this transformation. I tried with the below spec
[
{
"operation": "shift",
"spec": {
"*": "&",
"name": "attributes.&"
}
}
]
But this changes attributes field into an array. What should be the right spec used here?

The following spec would work
[
{
"operation": "shift",
"spec": {
"*": "&",
"name": "attributes.&",
"attributes": {
"*": "attributes.&"
}
}
}
]

Related

Map Jolt Transformation

I am trying to transform the following input:
{
"test_types": {
"3": "Type3",
"21": "type21",
"16": "Type16",
"15": "type15"
},
"name": "BlackSquid",
"obj_name": "malware",
"value": "2341743",
"type": "16"
}
Into this output:
{
"test_types": {
"3": "Type3",
"21": "type21",
"16": "Type16",
"15": "type15"
},
"name": "BlackSquid",
"obj_name": "malware",
"value": "2341743",
"type": "16",
"type_name": "Type16"
}
I have tried to use a "modify-overwrite-beta" spec by hardcoding the key value which gives me the result I need:
[
{
"operation": "modify-overwrite-beta",
"spec": {
"type_name": "#(1,test_types.16)"
}
}
]
but I would like to use the "type" value dynamically. The following throws an exception but maybe something like this:
[
{
"operation": "modify-overwrite-beta",
"spec": {
"type_name": "#(1,test_types.#(1,type))"
}
}
]
No need to use modify-overwrite-beta spec, but condition based shift spec for the key type would suffice such as
[{
"operation": "shift",
"spec": {
"*": "&",
"type": {
"*": {
"#(2,type)": "type",
"#(2,test_types.&)": "type_name"
}
}
}
}]

JOLT Nested if condition

I have this input JSON:
{
"user": "123456",
"product": "television",
"category": "electronics",
"tag": "summer"
}
And this transformation:
[
{
"operation": "shift",
"spec": {
"product": {
"#(1,product)": "item",
"#(1,user)": {
"#2": "userBias"
}
},
"user": {
"#(1,user)": "user"
},
"category": {
"#category": "rules.[0].name",
"#(1,category)": "rules.[0].values[0]"
},
"tag": {
"rules": "rules",
"#tag": "rules.[1].name",
"#(2,tag)": "rules.[1].values[0]"
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"userBias?": "=toInteger"
}
}
]
Which works fine and produces the following JSON:
{
"item": "television",
"userBias": 2,
"user": "123456",
"rules": [
{
"name": "category",
"values": [
"electronics"
]
},
{
"name": "tag",
"values": [
"summer"
]
}
]
}
If from the input though I delete "category": "electronics" so it becomes:
{
"user": "123456",
"product": "television",
"tag": "summer"
}
Then i get back the following result:
{
"item": "television",
"userBias": 2,
"user": "123456",
"rules": [
null,
{
"name": "tag",
"values": [
"summer"
]
}
]
}
The problem with the above is that it contains a null element inside the array and I do not know how to get rid of it. I have tried with recursivelySquashNulls but it does not work.
Also basically what am looking for is if both category and tag exist then tag should go to rules[1] if only tag exists then tag should go to rules[0].
Thanks in advance,
giannis
Because you specify tag and category elements individually. Rather, prefer putting them into the category rest by combining them under asterisked key notation such as
[
{
"operation": "shift",
"spec": {
"product": {
"#(1,product)": "item",
"#(1,user)": {
"#2": "userBias"
}
},
"user": {
"#(1,user)": "user"
},
"*": {
"$": "r[0].&.name",
"#(1,&)": "r[0].&.values[]"
}
}
},
{
"operation": "shift",
"spec": {
"*": "&",
"r": {
"*": { "*": "rules" }
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"userBias?": "=toInteger"
}
}
]
Result1 :
Result2(without "category": "electronics" pair for the Input) :

Add array inside object with same key in jolt spec

I would like to move the recommendations array by row_id key inside the investors with the same row_id
Original Json
{
"investors": [
{
"row_id": 1,
"name": "AAAA"
},
{
"row_id": 2,
"name": "BBBB"
}
],
"recommendations": [
{
"row_id": "1",
"title": "ABC"
},
{
"row_id": "2",
"title": "CDE"
}
]
}
I've tried a lot of specs at https://jolt-demo.appspot.com with no success
Specs tried...
[{
"operation": "shift",
"spec": {
"investors": {
"*": "investors[]"
},
"recommendations": {
"#": "recommendations[]"
}
}
}]
Desired Json
{
"investors": [
{
"row_id": 1,
"name": "AAAA",
"recommendations":[{
"row_id": "1",
"title": "ABC"
}]
},
{
"row_id": 2,
"name": "BBBB",
"recommendations":[{
"row_id": "2",
"title": "CDE"
}]
}
]
}
This can be done in two stage shift
First shift groups everything based on row_id.
(I'd suggest running the first shift of its own to see what the output is)
Second shift uses that grouped output and formats results.
[
{
"operation": "shift",
"spec": {
"*": {
"*": {
"row_id": {
"*": {
"#2": "&.&4"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"investors": "investors.[#2]",
"recommendations": "investors.[#2].recommendations[]"
}
}
}
]

Jolt grouping together and including new tags

I have the following input JSON and want to group the sub jsons according to device name.(Device name has to be extracted from address). Also, i want to add new tags to the new arrays formed(Each array contains jsons having that type of device name only).
I've already tried below spec but the array Name name is appearing as deviceName instead of custom Parameter(I don't know how to provide custom name. for example i want the array name as "Parameters"). I'm not able to extract the device name from address field.(Device Name should come as "bee"/"honey"). Also, I want to add a new field which should be there once for the new array (and not for each element).
Input Json:
{
"CID": "AND",
"parameters": [{
"address": "abc:api:honey",
"name": "CH1"
},
{
"address": "abc:api:honey",
"name": "CH2"
},
{
"address": "abc:api:bee",
"name": "lat"
},
{
"address": "abc:api:bee",
"name": "long"
}
],
"rNo": 1232
}
Expected Output:
[{
"ID": "AND_1232",
"parameters": [{
"deviceName": "honey",
"name": "CH1",
"locoId": 1232,
"CID": "AND"
},
{
"deviceName": "honey",
"name": "CH2",
"locoId": 1232,
"CID": "AND"
}
],
"SpData": {
}
},
{
"ID": "AND_1232",
"parameters": [{
"deviceName": "bee",
"name": "lat",
"locoId": 1232,
"CID": "AND"
},
{
"deviceName": "bee",
"name": "long",
"locoId": 1232,
"CID": "AND"
}
],
"SpData": {
}
}]
Spec I tried:
[
{
"operation": "shift",
"spec": {
"parameters": {
"*": {
"#(2,CID)": "&2.[&1].CID",
"*": "&2.[&1].&",
"#(2,rNo)": "&2.[&1].locoId"
}
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"ID": "=concat(#(0,CID),'_',#(0,rNo))",
"parameters": {
"*": {
"deviceName": "=substring(#(1,address),8,11)",
"SpData": {}
}
}
}
}, {
"operation": "shift",
"spec": {
"parameters": {
"*": {
"deviceName": {
"*": {
"#2": "&[]"
}
}
}
}
}
}
]
The following will output desired results, each operation does the following respectively:
Add ID by concatenating CID and rNo
Add rNo and CID to all parameters and add deviceName (see here for details on device name splitting).
Group records by deviceName using object
Add ID to each group
Convert temporary grouping to array
Add default SpData
[
{
"operation": "modify-default-beta",
"spec": {
"ID": "=concat(#(1,CID),'_',#(1,rNo))"
}
},
{
"operation": "shift",
"spec": {
"ID": "&",
"parameters": {
"*": {
"address": {
"*:*:*": {
"$(0,3)": "parameters.[&3].deviceName"
}
},
"#(0,name)": "parameters.[&].name",
"#(2,rNo)": "parameters.[&].locoId",
"#(2,CID)": "parameters.[&].CID"
}
}
}
},
{
"operation": "shift",
"spec": {
"ID": "&",
"parameters": {
"*": {
"deviceName": {
"*": {
"#(3,[&2])": "tmp.&.parameters.[]"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"tmp": {
"*": {
"#(2,ID)": "&1.ID",
"parameters": {
"#": "&2.parameters"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": "[]"
}
},
{
"operation": "default",
"spec": {
"*": {
"SpData": {}
}
}
}
]

Combining two arrays and transformation using Jolt

I am having a tough time using Jolt mapping trying to transform the input to the necessary form
Input JSON
{
"data": [
{
"name": "Alcohol",
"collection_id": 123,
"properties": [
{
"name": "Tax",
"property_id": "00001"
},
{
"name": "Expenditure",
"property_id": "00002"
}
],
"attributes": [
{
"name": "alcohol_tax",
"attribute_id": "00011"
},
{
"name": "alcohol_expenditure",
"attribute_id": "00022"
}
]
}
]
}
Output JSON
[
{
"name": "Alcohol",
"collection_id": 123,
"details": [{
"property_name": "Tax",
"property_id": "00001",
"attribute_id": "00011"
},
{
"property_name": "Expenditure",
"property_id": "00002",
"attribute_id": "00022"
}
]
}
]
I have tried a couple of ways to combine the arrays using a few rules but with little success.
One of the rules
[{
"operation": "shift",
"spec": {
"data": {
"*": {
"name": "&1.name",
"collection_id": "&1.collection_id",
"attributes": {
"*": {
"attribute_id": "&1.attribute_id[]"
}
},
"properties": {
"*": {
"name": "&1.myname[]",
"property_id": "&1.property_id[]"
}
}
}
}
}
}]
is adding all the attributes and properties to all the collections.I do not know why this happens as I thought &1.property_id[] would only add items in that particular collection to the array and not all collections. Any help/clues on why this is happening would be truly appreciated.
See solution below:
[0] creates the wrapping array
[&1] uses the position of the respective arrays so the results are combined in details the important part is wrapping square brackets so its treated as array rather than literal.
[
{
"operation": "shift",
"spec": {
"data": {
"*": {
"name": "[0].name",
"collection_id": "[0].collection_id",
"attributes": {
"*": {
"attribute_id": "[0].details.[&1].attribute_id"
}
},
"properties": {
"*": {
"name": "[0].details.[&1].name",
"property_id": "[0].details.[&1].property_id"
}
}
}
}
}
}
]
Produces the following:
[
{
"name": "Alcohol",
"collection_id": 123,
"details": [
{
"attribute_id": "00011",
"name": "Tax",
"property_id": "00001"
},
{
"attribute_id": "00022",
"name": "Expenditure",
"property_id": "00002"
}
]
}
]