Jolt Transform JSON Spec for List JSON Input - json

I am trying to do a JOLT shift transformation of an inputted JSON-list
Below my input:
[
{
"number": 1001,
"description": "KA01"
},
{
"number": 1002,
"description": "KA02"
}
]
And I want to create this output:
{
"actions" : [
{
"_type": "SetFieldValue",
"fieldName": "UUID",
"value": "uuid"
},
{ "_type": "InsertRow" },
{
"_type": "SetFieldValue",
"fieldName": "number",
"value": "1001"
},
{
"_type": "SetFieldValue",
"fieldName": "description",
"value": "KA01"
},
{ "_type": "InsertRow" },
{
"_type": "SetFieldValue",
"fieldName": "number",
"value": "1002"
},
{
"_type": "SetFieldValue",
"fieldName": "description",
"value": "KA02"
},
{
"_type": "SetFieldValue",
"fieldName": "start"
}
]
}
I havenĀ“t done much with JOLT transformation and need help in this case.

First of all you can divide the JSON value into parts by key names and values, and then add _type attributes as being default such as
[
{
"operation": "shift",
"spec": {
"*": {
"*": {
"$": "&1.[&2].fieldName",
"#": "&1.[&2].value"
}
},
"#UUID": "x[#2].fieldName",
"#uuid": "x[#2].value",
"#start": "y[#2].fieldName"
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": ""
}
}
},
{
"operation": "default",
"spec": {
"*": {
"_type": "SetFieldValue"
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"#": ""
},
"#InsertRow": "_type"
}
},
{
"operation": "sort",
"spec": {}
}
]

Related

Jolt Conversion - iterate list within a list and form single list

I am trying to iterate lists inside a list and form a single list with multiple objects. Iterating lists, I am able to achieve. But applying tags before the list iterating to each object is not happening if there are more objects in single list.
My input request is like below:
[
{
"success": [
{
"id": "4",
"Offers": [
{
"name": "Optional",
"type": {
"id": "1",
"name": "Optional"
},
"productOfferings": [
{
"id": "3",
"name": "Test1"
}
]
},
{
"name": "Default",
"type": {
"id": "2",
"name": "Default"
},
"productOfferings": [
{
"id": "1",
"name": "Test2"
},
{
"id": "2",
"name": "Test3"
}
]
}
]
}
]
}
]
My spec is like below:
[
{
"operation": "shift",
"spec": {
"*": {
"success": {
"*": {
"Offers": {
"*": {
"name": "[&1].[&3].typeName",
"type": {
"id": "[&2].[&4].typeNameId",
"name": "[&2].[&4].typeNameValue"
},
"productOfferings": {
"*": {
"id": "[&3].[&1].id",
"name": "[&3].[&1].name"
}
}
}
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": "[]"
}
}
}
]
Output Received from spec:
[
{
"typeName": "Optional",
"typeNameId": "1",
"typeNameValue": "Optional",
"id": "3",
"name": "Test1"
},
{
"typeName": "Default",
"typeNameId": "2",
"typeNameValue": "Default",
"id": "1",
"name": "Test2"
},
{
"id": "2",
"name": "Test3"
}
]
But Expected output is like below:
[
{
"typeName": "Optional",
"typeNameId": "1",
"typeNameValue": "Optional",
"id": "3",
"name": "Test1"
},
{
"typeName": "Default",
"typeNameId": "2",
"typeNameValue": "Default",
"id": "1",
"name": "Test2"
},
{
"typeName": "Default",
"typeNameId": "2",
"typeNameValue": "Default",
"id": "2",
"name": "Test3"
}
]
If there are more objects inside productOfferings object, I am not able to add typeName,typeNameId, typeNameValue to the actual object. Please help to fix this issue.
You seem just needing to collect all into the productOfferings array while prepending each key by the common identifier [&3].[&1] such as
[
{
"operation": "shift",
"spec": {
"*": {
"success": {
"*": {
"Offers": {
"*": {
"productOfferings": {
"*": {
"#(2,name)": "[&3].[&1].typeName",
"#(2,type.id)": "[&3].[&1].typeNameId",
"#(2,type.name)": "[&3].[&1].typeNameValue",
"*": "[&3].[&1].&"
}
}
}
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": "[]"
}
}
}
]

JOLT get only one value from an array inside an array

I've been trying to figure out how to get the first value out of an array in my events array in this JSON.
I think I must do something with Cardinality but I can't quite figure it out so any help would be appreciated.
This is what my JSON looks like
{
"rootid": "19718",
"clloadm": "2021-06-01T22:40:02",
"clload": "2021-06-01T21:21:39",
"date": "2021-05-25T21:52:30",
"events": [
{
"done": {
"id": "e0",
"value": "2021-05-29T08:08:19"
},
"id": "e0_event",
"started": {
"id": "e0",
"value": "2021-05-29T08:08:19"
},
"status": "complete"
},
{
"done": {
"id": "e1",
"value": "2021-05-27T02:20:25"
},
"id": "e1_event",
"started": {
"id": "e1",
"value": "2021-05-27T02:20:25"
},
"status": "complete"
},
{
"done": {
"id": "e2",
"value": "2021-05-29T08:08:19"
},
"id": "e2_event",
"started": {
"id": "e2",
"value": "2021-05-29T08:08:19"
},
"status": "complete"
},
{
"done": {
"id": "e3",
"value": "2021-05-29T08:08:19"
},
"id": "e3_event",
"started": {
"id": "e3",
"value": "2021-05-29T08:08:19"
},
"status": "complete"
},
{
"done": {
"id": "e4",
"value": "2021-05-29T08:08:19"
},
"id": "e4_event",
"started": {
"id": "e4",
"value": "2021-05-29T08:08:19"
},
"status": "complete"
}
],
"ids": [
{
"id": "id",
"source": "source",
"value": "value"
}
]
}
My Jolt Spec
[
{
"operation": "shift",
"spec": {
"*": "&",
"events": {
"*": {
"*": {
"#id": {
"e0": { "#(2,value)": "&" },
"e4": { "#(2,value)": "&" }
}
}
}
},
"ids": {
"*": {
"#value": "#id"
}
}
}
}
]
The result I get:
{
"rootid" : "19718",
"clloadm" : "2021-06-01T22:40:02",
"clload" : "2021-06-01T21:21:39",
"date" : "2021-05-25T21:52:30",
"e0" : [ "2021-05-29T08:08:19", "2021-05-29T08:08:19" ],
"e4" : [ "2021-05-29T08:08:19", "2021-05-29T08:08:19" ],
"id" : "value",
"new_id" : "value"
}
I would like the result to be more like this where only the first value is selected:
{
"rootid" : "19718",
"clloadm" : "2021-06-01T22:40:02",
"clload" : "2021-06-01T21:21:39",
"date" : "2021-05-25T21:52:30",
"e0" : "2021-05-29T08:08:19",
"e4" : "2021-05-29T08:08:19",
"id" : "value",
"new_id" : "value"
}
Edit:
I've tried adding the cardinality into my spec, but I can't seem to get the result I want.
[
{
"operation": "shift",
"spec": {
"*": "&",
"events": {
"*": {
"*": {
"#id": {
"e0": { "#(2,value)": "&" },
"e4": {
"operation": "cardinality",
"spec": {
"e4": "ONE"
}
}
}
}
}
},
"ids": {
"*": {
"#value": "#id"
}
}
}
}
]
Yes, you just can add a cardinality transformation such as
{
"operation": "cardinality",
"spec": {
"*": "ONE"
}
}
or optionally use e* wildcard just to restrict the result for the arrays with keys starting with the letter e such as
{
"operation": "cardinality",
"spec": {
"e*": "ONE"
}
}
Edit : just need to add to the current spec. So, you can use the following :
[
{
"operation": "shift",
"spec": {
"*": "&",
"events": {
"*": {
"*": {
"#id": {
"e0": {
"#(2,value)": "&"
},
"e4": {
"#(2,value)": "&"
}
}
}
}
},
"ids": {
"*": {
"#value": "#id"
}
}
}
},
{
"operation": "cardinality",
"spec": {
"e*": "ONE"
}
}
]

Key to value using jolt

I need to transform multiple keys and their values to new JSON spec using jolt.
Input:
{
"product": "monitor",
"ID": "222",
"price": "300"
}
Expected output:
{
"record": [
{
"key": "product",
"value": "monitor"
},
{
"key": "ID",
"value": "222"
},
{
"key": "price",
"value": "300"
}
]
}
Thanks in advance
Convert each node in the input json into key/value and shift to the named object. And then named object is moved to the array.
[
{
"operation": "shift",
"spec": {
"*": {
"#": "&1.value",
"$": "&1.key"
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"#": "records"
}
}
}
]

JOLT transformation for JSON originally from Protobuf format

I have json converted from protobuf protocol with following format:
{
"id": "6aa0734f-6d6a-4b95-8a2b-2dde346f9df7",
"measurements": [
{
"ts": "1590331111510000000",
"values": [
{},
{
"name": 1,
"value": -1.8093990087509155
},
{
"name": 2,
"value": 0.35456427931785583
}
],
"parameters": [
"Stat",
"VoltageAnglePhaseB"
]
}
]
}
expected output is:
{
"id" : "6aa0734f-6d6a-4b95-8a2b-2dde346f9df7",
"ts" : "1590331111510000000",
"Stat":-1.8093990087509155,
"VoltageAnglePhaseB":0.35456427931785583
}
I've started my Jolt spec like this:
[
{
"operation": "shift",
"spec": {
"id": "id",
"measurements": {
"*": {
"ts": "ts",
"parameters": {
"*": ""
},
"*": ""
}
}
}
}
]
But facing the problem to extract name and value from the JSON.
Does anyone have an idea?
It can be done with 2 shift operations. First, shift the values to the valuesArr, same way shift the parameters to the parametersArr. Then match the values with the index.
[
{
"operation": "shift",
"spec": {
"id": "id",
"measurements": {
"*": {
"ts": "ts",
"values": {
"*": {
"value": "valuesArr"
}
},
"parameters": "parametersArr"
}
}
}
},
{
"operation": "shift",
"spec": {
"id": "id",
"ts": "ts",
"valuesArr": {
"*": "#(2,parametersArr[&])"
}
}
}
]

Flattening data from 3 nested lists, into a single list using Jolt

The actual requirement is to fetch ;parent id in each json object as described in required output. The input contains array of children in hierarchy. The respective parent id ie. if id = A_B then its parent_id shall be A.
Jolt Spec Tried:
[{
"operation": "shift",
"spec": {
"children": {
"*": {
"id2": "&",
"name": "&",
"path": "&",
"#": "[&1]",
"#(2,id)": "[&1].parent_id",
"children": {
"*": {
"#": "[&1]",
"#(3,id2)": "[&1].parent_id2"
}
}
}
}
}
}]
#
INPUT
#
{
"categories": [
{
"id": "A",
"name": "firstName",
"path": "firstPath",
"children": [
{
"id": "A_B",
"name": "secondName",
"path": "secondPath",
"children": [
{
"id": "A_B_C",
"name": "thirdName",
"path": "thirdPath"
}
]
}
]
}
]
}
#
Required this OUTPUT
#
[{
"id": "A",
"name": "firstName",
"path": "firstPath",
"parentId": "0"
},
{
"id": "A_B",
"name": "secondName",
"path": "secondPath",
"parentId": "A"
},
{
"id": "A_B_C",
"name": "thirdName",
"path": "thirdPath",
"parentId": "A_B"
}]
Spec : Run each step individually to see what it is doing.
[
{
// bootstrap the root level to have "parentId": "0"
"operation": "default",
"spec": {
"categories[]": {
"0": {
"parentId": "0"
}
}
}
},
{
// Build the "data" object you want, but you have to do it
// maintaining the 3 levels of nested lists as the input
// so that the lookups will work.
"operation": "shift",
"spec": {
"categories": {
"*": {
"*": "root[&1].data.&",
"children": {
"*": {
"*": "root[&3].firstLevel[&1].data.&",
"#(2,id)": "root[&3].firstLevel[&1].data.parent_id",
"children": {
"*": {
"*": "root[&5].firstLevel[&3].secondLevel[&1].data.&",
"#(2,id)": "root[&5].firstLevel[&3].secondLevel[&1].data.parent_id"
}
}
}
}
}
}
}
},
{
// Lastly, accumulate all the finished "data" elements from the
// 3 nested arrays into a single top level array.
"operation": "shift",
"spec": {
"root": {
"*": {
"data": "[]",
"firstLevel": {
"*": {
"data": "[]",
"secondLevel": {
"*": {
"data": "[]"
}
}
}
}
}
}
}
}]