How to get column value of key in JOLT - json

I'm looking for breaking following nested JSON file and transform it into a SQL prepared format.
Input JSON file:
{
"Product1": {
"Purchase": 31
},
"Product2": {
"Purchase": 6213,
"Cancel": 1988,
"Change": 3702,
"Renewal": 5934
}
}
Desired output:
[
{
"product": "Product1",
"Purchase": 31
},
{
"product": "Product2",
"Purchase": 6213,
"Cancel": 1988,
"Change": 3702,
"Renewal": 5934
}
]

What you need is using a $ wildcard within a shift transformation spec in order to replicate the current attributes's key such as
[
{
"operation": "shift",
"spec": {
"*": {
"$": "[#2].product",// $ grabs the value after going tree one level up from the current level
"*": "[#2].&"// keeps the current attributes conforming to the objects nested within a common array
}
}
}
]

Related

How can I add key and values from one object into each object in an array via jolt

I'm using jolt and I have an input object where I would like to take the keys out of one property and insert them into each object of an array in another property:
My input:
{
"jolt_marketplaceMetadata": {
"NAN_KEY": 1,
"TEMP": 3
},
"jolt_attributes": [
{
"name": "HELLO",
"yyup": 3
},
{
"huh": "please",
"work": 2
}
]
}
The result I'm aiming for:
"jolt_attributes": [
{
"name": "HELLO",
"yyup": 3,
"NAN_KEY": 1,
"TEMP": 3
},
{
"huh": "please",
"work": 2,
"NAN_KEY": 1,
"TEMP": 3
}
]
I've tried a couple of different spec arrays and I've gotten pretty close, but I can't seem to figure out how to get the values in without merging all of the data from each of the objects in the array:
[
{
"operation": "shift",
"spec": {
"jolt_attributes": {
"*": {
"*": "jolt_attributes[&1].&",
"#(2,jolt_marketplaceMetadata)": "jolt_attributes[&1]"
}
}
}
}
]
which gives me:
{
"jolt_attributes": [
{
"NAN_KEY": 1,
"TEMP": 3,
"name": "HELLO",
"yyup": 3,
"huh": "please",
"work": 2
},
{
"NAN_KEY": 1,
"TEMP": 3,
"name": "HELLO",
"yyup": 3,
"huh": "please",
"work": 2
}
]
}
It adds the keys from jolt_marketplaceMetadata, but it also merges all of the key/values from each of the array objects together each time.
Any ideas??
You can use the following shift transformation spec
[
{
"operation": "shift",
"spec": {
"jolt_attributes": {
"*": {
"*": "&2[#2].&",
"#2,jolt_marketplaceMetadata.NAN_KEY": "&2[#2].NAN_KEY",
"#2,jolt_marketplaceMetadata.TEMP": "&2[#2].TEMP"
}
}
}
}
]
where
&2 replicates the key of the array ("jolt_attributes")
[#2] loops through the indexes of that array after traversing the
tree 2 levels(once for colon, once for opening curly brace) and generates arraywise(array of objects here) result
You can even make it more dynamic by using the following spec
[
{
"operation": "shift",
"spec": {
"*attributes": {
"*": {
"#2,jolt_marketplaceMetadata": { "*": "&3[&1].&" }, // &3 represents going two levels up the tree to get the literal "jolt_attributes"
"*": "&2[&1].&" // &2 represents going two levels up the tree to get the literal "jolt_attributes"; [&1] stands for bringing the values of the indexes of the "jolt_attributes" in array-wise manner.
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

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.

Match JSON arrays with JOLT

I have JSON from REST API:
{
"fields": [
"advertiser_id",
"campaign_id",
"day"
],
"data": [
[
"8905",
"234870",
"2021-09-28"
],
[
"5634",
"88467870",
"2021-09-28"
]
]
}
I want to match values inside fields array with values inside data. The have same order. So I expect to get:
[
{
"advertiser_id": "8905",
"campaign_id": "234870",
"day": "2021-09-28"
},
{
"advertiser_id": "5634",
"campaign_id": "88467870",
"day": "2021-09-28"
}
]
Any ways to do it with JOLT?
You can use a shift transformation spec in which
go 4 levels up (traverse once:, and { triple) in order to reach
fields array as picking sub-arrays of data array by using [&1]
dissipate all returning key-value pairs through use of [&2]. node
such as
[
{
"operation": "shift",
"spec": {
"data": {
"*": {
"*": {
"#": "[&2].#(4,fields[&1])"
}
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

Apache Nifi transform with JoltTranform processor

I have some attributes myId, count. Now with these attributes I want write down the Jolt format to get the following output.
{
"projectId": "projectId",
"ticketId": "NO_TICKET",
"trigger": "SCHEDULED_BACKLOG",
"timestamp": 1539060316494,
"pivotVersion": 1,
"pivotType": "FlattenedTodoStats",
"todoCount": "todoCount",
"pivots": [
{
"state": "BACKLOG",
"type": "NA"
}
]
}
You can either use Jolt Transform (or) ReplaceText processors for this case.
As you are having some attributes to the flowfile so use ReplaceText processor
In ReplaceMent Value configure as
{
"projectId": "${projectId}",
"ticketId": "${ticketId}",
"trigger": "${trigger}",
"timestamp": "${timestamp}",
"pivotVersion":"${pivotVersion}",
"pivotType":"${pivotType}",
"todoCount":"${todoCount}",
"pivots[]": {
"*": {
"state": "${state}",
"type": "${type}"
}
}
}
Substitute all the attribute names(${projectId}..etc) with your attribute names.
Use Replacement Strategy as AlwaysReplace
(or)
If you want to use Jolt for this case then
Use default operation to replace your attribute values and prepare json message
Example:
Jolt Specification
[{ "operation": "shift", "spec": { "z":"z" } }, { "operation": "default", "spec": { "projectId": "${projectId}", "ticketId": "${ticketId}", "trigger": "${trigger}", "timestamp": "${timestamp}", "pivotVersion":"${pivotVersion}", "pivotType":"${pivotType}", "todoCount":"${todoCount}", "pivots[]": { "*": { "state": "${state}", "type": "${type}" } } } }]
As i don't have any attribute values, so my output json is having all empty values in it.
Change the spec jolt spec as per your requirements.

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]
}
}
}
}
}
]