Jolt - Get values using a list of keys, alternatives to #(2,#) - apache-nifi

I need to create a JSON array in order to split it into several jobs with Nifi.
The array needs to be created based on an existing array inside the JSON.
Can't figure out how to dynamically create a reference to another object in the JSON. I want the reference "#(2,#)" to work, but this is not supported.
INPUT
{
"name": "Loki",
"id": "1234",
"loc": "Utgard",
"age": "unknown",
"listitems": [
"name",
"id"
]
}
SPEC (that doesn't work):
[
{
"operation": "shift",
"spec": {
// Loop all listitems
"listitems": {
"*": {
// Get the value of the current item and push to processlist.type array
"#": "processlist[#2].type",
// Here is the problem, I need to get the "top level" value for the current value/key
"#(2,#)": "processlist[#2].value"
}
}
}
}
]
Expected output:
{
"processlist" : [
{
"type" : "name",
"value" : "Loki"
}, {
"type" : "id",
"value" : "1234"
}
]
}
SPEC (that will run but is not correct)
[
{
"operation": "shift",
"spec": {
// Loop all listitems
"listitems": {
"*": {
// Get the value of the current item and push to processlist.type array
"#": "processlist[#2].type",
// Here is the problem, I need to get the top level value for the current value/key
// Forcing this to "name" will at least execute the code
"#(2,name)": "processlist[#2].value"
}
}
}
}
]
Any ideas?

You can proceed one more step by adding "*" key to nest the current spec more while roaming by #(3,&) dynamically as this ampersand represents the incurred key values name and id such as
[
{
"operation": "shift",
"spec": {
"listitems": {
"*": {
"*": {
"#1": "processlist[#3].type",
"#(3,&)": "processlist[#3].value"
}
}
}
}
}
]

Related

How to add new key in json flow by nifi jolt processor

how to convert the following data
{
"name" : "abcd",
"middleName" : "srivastav"
}
into
{
"name" : "abcd",
"middleName" : "srivastav"
"id" : "abcd"
}
by using a jolt transform such that the id and the name are within the same object as the expected output.
modify-default-beta or default operations will work for this :
[
{
"operation": "modify-default-beta",
"spec": {
"id": "abcd"
}
}
]
One option is to replicate the value of name through use of "#(0,name)": while keeping the current attributes by "*": "&" notation within a shift transformation such as
[
{
"operation": "shift",
"spec": {
"*": "&",
"#(0,name)": "id"
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is
or another option is to use a modify(overwrite/default) transformation to dynamically replicate the value of name attribute for id such as
[
{
"operation": "modify-overwrite-beta",
"spec": {
"id": "#(1,name)"
}
}
]
the second demo is

Convert two arrays into single array of objects

I have two arrays and need to convert these arrays into a single object array using jolt.
Input
"Name": ["Test Test", "Test2 Test"]
"email": ["Test#tesasds.com", "Test2#test.com"]
output
[{"Name":"Test Test","email":"Test#tesasds.com"},{"Name":"Test2 Test","email":"Test2#test.com"}]
Description inline:
[
{
"operation": "shift",
"spec": {
// for every key
"*": {
// and every item in the array
"*": {
// create a structure <index of array> : key : value
// This will therefore join the two because the indexes will be the same
"#": "&.&2"
}
}
}
},
{
//Remove the index as key
"operation": "shift",
"spec": {
"*": "[]"
}
}
]
I'd suggest running the first shift to get understanding of the description.

Jolt Spec for moving the json objects into the simple array

I am having an array of objects in the given format:
[
{
"meta": [
{
"id": "101A"
},
{
"id": "101B"
}
]
}
]
Can someone help me with jolt spec I want the final output in the following format:
[
{
"meta": [
"101A",
"101B",
......
]
}
]
Thanks in advance!
Basically you want to iterate over your two arrays using the "*", and when iterating over your second array (meta) just get the id attribute and send to the meta array (ignore the object). See if this helps you understand:
[
{
"operation": "shift",
"spec": {
"*": {
"meta": {
"*": {
"id": "meta"
}
}
}
}
}
]

I have Json array with each of its object having dynamic attributes. I have to merge all the object into into one Json object in nifi

I have Json array with each of its object having dynamic attributes. I have to merge all the object into one Json object in nifi with common attribute's value concatenated and other attributes as it is.
I have already tried following spec, and it is giving common attributes as array list. But I want that common attribute's value to be concatenated and I don't know how to do that. Any suggestion would be really helpful. Thanks in advance.
[
{
"operation": "shift",
"spec": {
"*": {
"*": "&"
}
}
}
]
The input is like( NOTE: The attributes are dynamic so not sure always going to have these attributes)
[
{
"firstName": "Sam1",
"lastName": "Achom1",
"place": "Silchar1"
},
{
"firstName": "Saya2",
"lastName": "Singh2",
"place": "Macherial2",
"Second1stAttribute": "SomeValue"
},
{
"firstName": "Sam3",
"lastName": "Achom3",
"place": "Silchar3",
"Third2ndAttribute": "SomeValue2"
}
]
The output I am getting with before mentioned spec
{
"firstName" : [ "Sam1", "Saya2", "Sam3" ],
"lastName" : [ "Achom1", "Singh2", "Achom3" ],
"place" : [ "Silchar1", "Macherial2", "Silchar3" ],
"Second1stAttribute" : "SomeValue",
"Third2ndAttribute" : "SomeValue2"
}
And Expecting the output as
{ "firstName" : "Sam1 Saya2 Sam3",
"lastName" : "Achom1 Singh2 Achom3",
"place" : "Silchar1 Mancherial2 Silchar3",
"Second1stAttribute" : "SomeValue",
"Third2ndAttribute" : "SomeValue2"
}
You can "join" the items from your arrays. This spec will do the trick:
[
{
"operation": "shift",
"spec": {
"*": {
"*": "&"
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"*": "=join(' ',#(1,&))"
}
}
]

How to recursively iterate over a tag using jolt

I need to transform JSON using jolt. Input JSON is as follows:
{
"items": [
{
"Group1": {
"ABCCode": "3",
"ABCDescription": "abcd"
},
"Group2": {
"test2": [
"123"
]
}
}
]
}
and I need the output as the following,
[
{
"test2Id": "123",
"attrname": "ABCCode",
"attrval": "3"
},
{
"test2Id": "123",
"attrname": "ABCDescription",
"attrval": "abcd"
}
]
How can I achieve this using jolt?
This produces the output from the given input. You will probably need to tweak it, as you give it different types of input.
[
{
"operation": "shift",
"spec": {
"items": {
"*": {
"Group1": {
// match all keys below Group1
"*": {
// "$" means grab the key matched above,
// and write it the the output as "attrname"
"$": "[#2].attrname",
// "#" means grab the value matched above
"#": "[#2].attrval",
// walk back up the match tree three levels
// walk back down the path "Group2.test2[0]"
// and write that value to the output
"#(2,Group2.test2[0])": "[#2].test2Id"
}
}
}
}
}
}
]

Resources