JOLT tranform elements based on key - json

I am trying to find out correct JOLT specification file for below:
Input file:
{
"network": "A",
"ips": {
"subnet1": "1.1.1.1",
"subnet2": "1.1.1.2",
"subnet3": "1.1.1.3",
"subnet4": "1.1.1.4"
}
}
Output file:
{
"allValues": [
{
"network": "A",
"ips": {
"subnet1": "1.1.1.1",
"subnet2": "1.1.1.2"
}
},
{
"network": "A",
"ips": {
"subnet3": "1.1.1.3",
"subnet4": "1.1.1.4"
}
}
]
}
Based on subnet values, I want to group the IPs(subnet1 and subnet2 in one) and (subnet3 and subnet4 in another), while all should have network value(A).
Can somebody please help.

If you know which subnets belong together (subnet1 and subnet2 for example), you can use something like the following:
[
{
"operation": "shift",
"spec": {
"ips": {
"subnet1": "allValues[0].ips.subnet1",
"subnet2": "allValues[0].ips.subnet2",
"subnet3": "allValues[1].ips.subnet3",
"subnet4": "allValues[1].ips.subnet4"
},
"network": "allValues[0].network",
"#(0,network)": "allValues[1].network"
}
}
]

Related

How does the jolt wildcards work for RHS?

I'm trying to understand the working of '#' wild card.
I have used the '#' in the spec while preparing the productList and it works and I got the output as per my expectation. But I'm not sure about the working of it.
Can anyone please help me to understand the working of it?
Here is the input JSON
{
"orders": [
{
"order_parts": [
{
"id": "0001",
"items": [
{
"id": "00101",
"goodIdentificationList": [
{
"goodIdentificationTypeId": "UPCA",
"idValue": "42684666380437"
},
{
"idValue": "V-ASHBY",
"goodIdentificationTypeId": "SHOPIFY_PROD_SKU"
}
],
"productName": "BLACK / 6 / 809"
},
{
"id": "00102",
"goodIdentificationList": [
{
"goodIdentificationTypeId": "SHOPIFY_PROD_ID",
"idValue": "42684666380437"
},
{
"idValue": "V-ASHBY",
"goodIdentificationTypeId": "UPCA"
}
],
"productName": "BLACK / 6 / 809"
}
]
},
{
"id": "0002",
"items": [
{
"id": "00103",
"goodIdentificationList": [
{
"goodIdentificationTypeId": "SHOPIFY_PROD_ID",
"idValue": "42684666380437"
},
{
"idValue": "V-ASHBY",
"goodIdentificationTypeId": "UPCA"
}
],
"productName": "BLACK / 6 / 809"
}
]
}
]
}
]
}
Expected by the below spec:-
Check every map of goodIdentificationList, get the idValue where goodIdentificationTypeId - UPCA, and put in the productList as gtin.
Get the id from the items list and put it in the productList as an itemId.
Get the productName from the items list and put it in the productList as a name.
Jolt Spec is like below
[
{
"operation": "shift",
"spec": {
"orders": {
"*": {
"order_parts": {
"*": {
"items": {
"*": {
"goodIdentificationList": {
"*": {
"goodIdentificationTypeId": {
"UPCA": {
"#(2,idValue)": "[&5].productList.[#8].gtin"
}
}
}
},
"id": "[&1].productList.[#4].itemId",
"productName": "[&1].productList.[#4].name"
}
}
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"productList": {
"*": "productList.[]"
}
}
}
}
]
By the above spec, I'm able to prepare the productList as I was expecting.
But want to understand the working of '#' here.
Output JSON
{
"productList" : [ {
"itemId" : "00101",
"name" : "BLACK / 6 / 809"
}, {
"itemId" : "00103",
"name" : "BLACK / 6 / 809"
}, {
"itemId" : "00102",
"name" : "BLACK / 6 / 809"
} ]
}
Any help will be appreciated.
Thanks!
You principally need this spec
[
{
"operation": "shift",
"spec": {
"order*": {
"*": {
"order*": {
"*": {
"items": {
"*": {
"id": "&3.&1.&",
"prod*": "&3.&1.&"
}
}
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": "productList[]"
}
}
}
]
in which, the combination of the indexes of "items" array(&1) vs. the indexes of "order_parts" array(&3) handles separation of three individual objects, and then then tiding up innermost part while tagging the desired value(productList), and combining those newly generated objects will spontaneously form an array.
Replacement of
"id": "&3.&1.&",
"prod*": "&3.&1.&"
with
"id": "&3[&1].&",
"prod*": "&3[&1].&"
or
"id": "&3[#2].&",
"prod*": "&3[#2].&"
would handle exactly the same for this current case. But if there was no array the identifiers [&1] or [#2] would produce square brackets. The difference for right-hand-size usage of them is [&1] will traverse {, while [#2] will traverse both { and the current : characters in order to reach the target within the current tree, and [&1] will use indexes 0,1,2, which starts from zero, everytime and this will generate some null components for generated arrays for some cases, while [#2] won't. Eg. On the RHS of the spec, # is only valid in the the context of an array, like "[#2]".What "[#2]" means is, go up the three levels(including the colon at the current level) and ask that node how many matches it has had, and then use that as an index in the arrays.

Merge separate flow files with separate JSON together in Nifi

I am attempting to merge two flowfiles together using MergeContent. The content of both files are JSON objects which I would like to append to each other and wrap both with a JSON key.
File 1:
"Create":[
{
"Action": "Create",
"Book": {
"Id": "1234"
}
},
{
"Action": "Create",
"Video": {
"Id": 3245
}
}
]
File 2:
"Update":[
{
"Action": "Update",
"Book": {
"Id": "5376"
}
},
{
"Action": "Update",
"Video": {
"Id": "8267"
}
}
]
I need the final output to look like so:
{
"Transaction": {
"Action": "Transaction",
"Type": {
"Create": [
{fill in stuff}
],
"Update": [
{fill in stuff}
]
}
}
}
What is happening is that my MergeContent processor is picking up more than one flow file out of the Update or Create input and it is merging 'like' flow files together, instead of merging the separate content together.
Screenshot of my MergeContent :
You can add a MergeContent processor with
Delimiter Strategy = Text
Header = {
Footer = }
Demarcator = ,
in order to generate the core part
"Create": [
{fill in stuff}
],
"Update": [
{fill in stuff}
]
then apply a JSONJoltTransform with specification
[
{
"operation": "shift",
"spec": {
"#Transaction": "&.Action",
"#": "Transaction.Type"
}
}
]
in order to convert them to a formatted JSON value as desired such as

Jolt Transformation - json contains resut format

The body of the request consists of 2 objects, one of which is the payload, and the other is a description, since the payload must be transformed for transmission to the next system.
Please, help write a specification for such a format:
body:
{
"input":{
"items":[
{
"id":1,
"name":"items1",
"statusId":5
},
{
"id":7,
"name":"items7",
"statusId":2
},
...
{
"id":N, // any number
"name":"itemsN",
"statusId":1
}
]
},
"output":[
{
"target":"sg_id",
"source":"id",
"type":"list"
},
{
"target":"sg_name",
"source":"name",
"type":"list"
}
]}
result:
{
"items":{
"sg_id":[
1,
7,
...
N
],
"sg_name":[
"items1",
"items7",
...
"itemsN"
]
}}
You can use a shift operation through prepending desired aliases with the title(item.) of the array such as
[{
"operation": "shift",
"spec": {
"input": {
"items": {
"*": {
"id": "items.sg_id",
"name": "items.sg_name"
}
}
}
}
}]

Jolt how to do this transform? Concat and set in array

I have an input like this
{
"employee": {
"id": "123456",
"firstName": "John",
"prefFirstName": "Doe",
"lastName": "John",
"prefLastName": "John",
"mgrFirstName": "Mitch",
"mgrPrefFirstName": "Mitch",
"mgrLastName": "McEvoy",
"mgrPrefLastName": "McEvoy",
"gmFirstName": "GMName",
"gmPrefFirstName": "GMName",
"gmLastName": "GMLastName",
"gmPrefLastName": "GMLastName",
"dirFirstName": "DirFirstName",
"dirPrefFirstName": "DirFirstName",
"dirLastName": "DirLastName",
"dirPrefLastName": "DirLastName",
}
}
Expected output should be like this, I can't figure out the fields in bold.
"managers" : [ {
"chnl" : "eml",
"nm": "Mitch McEvoy",
“mgrlbl”: “Direct Manager”
}, {
"chnl" : "eml",
"eml" : "",
"nm": "GMName GMLastName",
“mgrlbl”: “General Manager”
}, {
"chnl" : "eml",
"eml" : "",
"nm": "DirFirstName DirLastName",
“mgrlbl”: “Director”
} ],
"nhstdt" : "2020-11-23",
"nhmob" : "",
"nheml" : "empp#web.com",
"mgreml" : [ "testttt#web.com", "testttt#web.com" ],
"mgrchnl" : "email",
"chnl" : "mob",
"nhnm" : "Doe John",
"mgrnm" : "Mitch McEvoy"
I have a transform like this but can't figure out how to get the desired output:
[
{
"operation": "shift",
"spec": {
"employee": {
"prefFirstName": {
"*": {
"#1": "tmpFirstName",
"#(2,prefLastName)": "tmpLastName"
},
"": {
"#(2,firstName)": "tmpFirstName",
"#(2,lastName)": "tmpLastName"
}
},
"mgrPrefFirstName": {
"*": {
"#1": "tmpMgrFirstName",
"#(2,mgrPrefLastName)": "tmpMgrLastName"
},
"": {
"#(2,mgrFirstName)": "tmpMgrFirstName",
"#(2,mgrLastName)": "tmpMgrLastName"
}
},
"mgrName": "managers[0].nm",
"mgrBusEmail": "managers[0].eml",
"gmName": "managers[1].nm",
"gmBusEmail": "managers[1].eml",
"dirName": "managers[2].nm",
"dirBusEmail": "managers[2].eml",
"#eml": ["managers[0].chnl", "managers[1].chnl", "managers[2].chnl"]
}
}
},
{
"operation": "modify-default-beta",
"spec": {
"nhnm": "=concat(#(1,tmpFirstName),' ',#(1,tmpLastName))",
"mgrnm": "=concat(#(1,tmpMgrFirstName),' ',#(1,tmpMgrLastName))"
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"mode": ["=toInteger", 0]
}
}
]
But I am not able to figure out how do I concatenate mgrFirstName and mgrLastName, gmFirstName and gmLastName, dirFirstName and dirLastName and after concatenation I need to set this in the array managers[0], managers[1] and managers[2] respectively.
I am not able to figure how do I modify an array which is in my shift spec after I concat the stirngs.
You can do the concatenation first with a modify-default-beta spec, then set the desired fields in the array. This should get you started:
[
{
"operation": "modify-default-beta",
"spec": {
"employee": {
"mgrFullName": "=concat(#(1,mgrFirstName),' ',#(1,mgrLastName))",
"gmFullName": "=concat(#(1,gmFirstName),' ',#(1,gmLastName))",
"dirFullName": "=concat(#(1,dirFirstName),' ',#(1,dirLastName))"
}
}
},
{
"operation": "shift",
"spec": {
"employee": {
"mgrFullName": "managers[0].nm",
"mgrBusEmail": "managers[0].eml",
"gmFullName": "managers[1].nm",
"gmBusEmail": "managers[1].eml",
"dirFullName": "managers[2].nm",
"dirBusEmail": "managers[2].eml",
"#eml": ["managers[0].chnl", "managers[1].chnl", "managers[2].chnl"],
"#Direct Manager": "managers[0].mgrlbl",
"#General Manager": "managers[1].mgrlbl",
"#Director": "managers[2].mgrlbl"
}
}
}
]

How to get multiple array value as object

Hi I am new to JOLT transformation. I need to transform the input json using JOLT to get below seen output. Please help me in below transformation:
input:
{
"image": [
"content1",
"content2",
"content3"
],
"legal": [
"legal1",
"legal2",
"legal3"
],
"hyper": [
"hyper1",
"hyper2",
"hyper3"
]
}
output:
[
{
"image": "content1",
"legal": "legal1",
"hyper": "hyper1"
},
{
"image": "content1",
"legal": "legal1",
"hyper": "hyper1"
},
{
"image": "content1",
"legal": "legal1",
"hyper": "hyper1"
}
]
Spec
[
{
"operation": "shift",
"spec": {
"*": { // image, legal, etc
"*": { // array
"*": { // content1, legal1, etc
"$": "[&2].&3" // grab "content1" and use it as output
// send it to an output doc that is a top level array
// indexed by looking 3 levels up the tree [&2]
}
}
}
}
}
]