How to perform mapping values in jolt - transformation

I am trying to perform conditional mapping of values from the following JSON.
My input,
{
"rating": [
{
"id": 1,
"locations": [
{
"num": 1
},
{
"num": 2
}
]
}
]
}
Expected output:
{
"rating": [
{
"id": 1,
"locations": [
{
"num": 1
}
],
"new_locations": [
{
"num": 2
}
]
}
]
}
My spec,
[
{
"operation": "shift",
"spec": {
"rating": {
"*": {
"locations": {
"*": {
"num": "#(3,id)"
}
}
}
}
}
}
]
If the num value matches with id,then it should stay in location array else should be moved to new_locations.
Can anyone please suggest me help.Thanks.

There isn't a way to do that kind of conditional matching logic with the "out of the box" Jolt transforms.

Related

How to add a keyname to every element in an array in Nifi (Json)

I am quite new to Nifi and I already run into an issue:
I have a list of items in an array:
{
"locations": [
1,
2,
3
]
}
I want to transform this to:
{
"locations": [
{
"locationid": 1
},
{
"locationid": 2
},
{
"locationid": 3
}
]
}
Any ideas?
(After this I also want to add another element from a nifi attribute, but I think I will be able to manage that myself.)
Never mind:
[
{
"operation": "shift",
"spec": {
"locations": {
"*": {
"#": "[#2].locationID"
}
}
}
},
{
"operation": "modify-default-beta",
"spec": {
"*": {
"ReportTimestamp": "${ReportTimestamp:toDate('yyyy-MM-dd HH:mm:ss'):toNumber()}"
}
}
}
]

JOLT - Join arrays in nested array

I am trying to achieve the following transformation. However, my solution adds undesired null values into the final array.
The transformation needs to shift names in child array for all root elements. I have created 3 cases to illustrate the problem.
Case 1
Input
{
"root": [
{
"child": [
{
"name": "John"
},
{
"name": "Frazer"
}
]
},
{
"child": [
{
"name": "Brandon"
},
{
"name": "Josef"
}
]
}
]
}
Desired Output
{
"NAMES": ["John,Frazer","Brandon,Josef"]
}
Case 2: One child is empty
Input
{
"root": [
{
"child": []
},
{
"child": [
{
"name": "Brandon"
},
{
"name": "Josef"
}
]
}
]
}
Desired Output
{
"NAMES": ["","Brandon,Josef"]
}
Case 3: All childs are empty
Input
{
"root": [
{
"child": []
},
{
"child": []
}
]
}
Desired Output
{
"NAMES": ["",""]
}
EDIT: root array will always have at least 1 element.
Current JOLT spec works fine except for cases where child is an empty array. It generates null values and I'm trying to specify an empty string instead (or any hardcoded string value such as "NO_NAMES")
[
{
"operation": "shift",
"spec": {
"root": {
"*": {
"child": {
"*": {
"name": "NAMES[&3]"
}
}
}
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"NAMES": {
"*": "=trim"
}
}
},
{
"operation": "cardinality",
"spec": {
"NAMES": "MANY"
}
},
{
"operation": "default",
"spec": {
"NAMES": []
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"NAMES": {
"*": "=join(',',#0)"
}
}
}
]
You can apply consecutive transformations modify-overwrite-beta and then shift in order to determine comma-seperated elements of the list(unless they have zero size,this case only double quotes will appear), and then concatenate them within a list such as
[
{
"operation": "modify-overwrite-beta",
"spec": {
"root": {
"*": {
"child": { "*": "#(0,name)" },
"NAMES": "=join(',',#(1,child))"
}
}
}
},
{
"operation": "shift",
"spec": {
"root": {
"*": {
"NAMES": "&"
}
}
}
}
]

Unable to transform into below format json using Jolt transformation

Unable to achieve above output format using jolt and gone through multiple SO questions and could not find similar one. Tried with adding indexes inside array of jolt spec but did not work.
Thanks in Advance and find the input, output and jolt spec at below
Input:
{
"test1": "Student",
"School": {
"Syllabus": {
"Midterm": {
"inclusions": {
"includedSubjectsList": {
"Subjects": [
{
"subjectName": "MH1"
},
{
"subjectName": "MH2"
},
{
"subjectName": "MH3"
},
{
"subjectName": "MH4"
}
]
}
}
}
}
}
}
Jolt Spec:
[
{
"operation": "shift",
"spec": {
"School": {
"Syllabus": {
"Midterm": {
"inclusions": {
"includedSubjectsList": {
"Subjects": {
"*": {
"subjectName": "Academy[].books[]"
}
}
}
}
}
}
}
}
}
]
Current output:
{
"Academy": [
{
"books": [
"MH1"
]
},
{
"books": [
"MH2"
]
},
{
"books": [
"MH3"
]
},
{
"books": [
"MH4"
]
}
]
}
Expected output:
{
"Academy": [
{
"books": [
"MH1",
"MH2",
"MH3",
"MH4"
]
}
]
}
You are almost right. Replace
"subjectName": "Academy[].books[]"
with
"subjectName": "Academy[0].books[]"

Need jolt specs for below transformation

could anyone help to convert below mention input json to desired output json using jolt ?
Here in treefield list i want to fetch "paramid" and "paramvalue" to first level for only matched "paramid", rest of the list items should be intact in that treefield list.
e.g i want to take paramid "k1" with its value to first level as mentioned in the output.
Input
{
"A": "value1",
"B": "value2",
"C": {
"D": "x1",
"E": {
"treefield": [
{
"paramid": "k1",
"paramvalue": {
"string": "value1"
}
},
{
"paramid": "k2",
"paramvalue": {
"string": "value2"
}
},
{
"paramid": "k3",
"paramvalue": {
"string": "value3"
}
}
]
},
"F": {
"a": "x1",
"x": {
"y": 1
}
},
"H": "x4"
}
}
]```
**Output**
```[
{
"A": "value1",
"B": "value2",
"C": {
"D": "x1",
"E": {
"treefield": [
{
"paramid": "k1",
"paramvalue": {
"string": "value1"
}
},
{
"paramid": "k3",
"paramvalue": {
"string": "value3"
}
}
]
},
"F": {
"a": "x1",
"x": {
"y": 1
}
},
"H": "x4"
},
"k2": "value2"
}
]```
If I understand what you're trying to do (pull out key/value pairs and put them at the top level), this spec should do it:
[
{
"operation": "shift",
"spec": {
"C": {
"E": {
"treefield": {
"*": {
"paramvalue": {
"string": "#(2,paramid)"
}
}
}
},
"*": "&"
},
"*": "&"
}
}
]
That works on individual JSON objects. In your sample input you don't have a leading array bracket but you do have a trailing one, so if you expect multiple objects in an array and want them output in an array, this spec should work:
[
{
"operation": "shift",
"spec": {
"*": {
"C": {
"E": {
"treefield": {
"*": {
"paramvalue": {
"string": "[&6].#(2,paramid)"
}
}
}
},
"*": "[&2].&"
},
"*": "[&1].&"
}
}
}
]

Simple jolt transformation

I'm struggling with a very simple jolt transformation. I want to copy the whole input json (structure not known) into an array in the output json.
So for example the input could be:
{
"rating": {
"quality": {
"value": 3,
"max": 5
}
}
}
The output should look like this:
{
"items": [{
"item": {
"rating": {
"quality": {
"value": 3,
"max": 5
}
}
}
}]
}
Basically put the whole input json into an object called item into an array called items.
Could you please help me?
thx
I found the solution by myself. The required spec is
[
{
"operation": "shift",
"spec": {
"#1": {
"#": "items[].item"
}
}
}
]
[
{
"operation": "shift",
"spec": {
"#": "items[0].item"
}
}
]

Resources