Ignoring implicit Array creation in the output JSON - jolt

So currently if the input is
{
"foo": "bar",
"tuna": "marlin"
}
The spec is
[
{
"operation": "shift",
"spec": {
"foo": "baz",
"tuna": "baz"
}
}
]
The output is
{
"baz" : [ "bar", "marlin" ]
}
How do I make jolt not to create an array, but instead override the values of the "baz" key with the last element of the array?
Expected output
{
"baz" : "marlin"
}

As far as I understand, you only want to get the last element of the array. So, add one more spec to yours of operation type modify-overwrite-beta along with lastElement() function such as
[
{
"operation": "shift",
"spec": {
"*": "baz"
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"*": "=lastElement(#(1,&))"
}
}
]
in which no need to explicitly write each key within the shift spec, rather replace them with an asterisk. Then, the asterisk within the second spec also represents all of the keys(in this case, this is only baz), and ampersand next to that copies the name of the key in order to represent the relative value.

Related

How to read nested value using shift operation in JOLT

May be this is very basic but I am new to JOLT and I am not getting the expected output after several attempts.
I am trying to read a nested value using shift operation.
Basically the value of person is dynamic and based on this value, I need to read the value from profession object.
The input I am working on is huge and everything is working as expected, so I am just putting the part where I am stuck.
Input:
{
"person": "Tom Hanks",
"profession": {
"Tom Hanks": "actor",
"Christopher Nolan": "director"
}
}
Expected output:
{
"output" : "actor"
}
I am trying to achieve this using something like below. I know this is not correct format but just putting it to know if there is something like this which can be used to get the expected output.
[
{
"operation": "shift",
"spec": {
"#(1,profession).#(1,person)": "output"
}
}
]
Can someone please help.
Thanks in advance !!
I transformed the value as a key to match it with & operator. Maybe a more elegant way exists.
[
{
"operation": "shift",
"spec": {
"profession": "#(1,person)"
}
},
{
"operation": "shift",
"spec": {
"*": {
"&": "output"
}
}
}
]

Jolt transformation to retrieve key as value

I have this JSON input that I would like to transform via jolt spec
{
"message": {
"trx": {
"trxId": "1234"
},
"translation": {
"transactions": {
"1234": "http://www.trythisjolt.com"
}
}
}
}
expected output would be something like this
{
"message": {
"trx": {
"trxId": "1234",
"trxName": "http://www.trythisjolt.com"
}
}
}
Is this achievable with Jolt please? I have tried several possibilities but I'm very new to Jolt and have not managed so far
Yes achievable, you can use
[
{
"operation": "shift",
"spec": {
"*": {
"*": {
"trxId": "message.trx.&",
"transactions": { "*": "message.trx.trxName" }
}
}
}
}
]
where go to the innermost elements firstly, then prepend message.trx. for both while renaming the second one to the desired value. This way, both of them are nested within the common object.

Newbie: Transform json repetitions to Single Arrays and add Entry Inside

I'm looking for some Jolt help. I'm officially a newbie attempting to understand if Jolt will suffice for usage in our solution. I can't seem to get the following output as I would expect.
I was wondering if anyone could help me, and see if this template would be able to help out on our other needs for structures of the same fashion. Also, if anyone has the best/better reading they suggest on Jolt, I'm happy to hear of that as well.
In a nutshell, I'm trying to use JOLT to handle the following Needs:
From a JSON input, if there are multiple repetitions of a structure, output these repetitions as an array of the independent json structures.
From the parent level, take a named match SetIDAL1 and place into the top created json structure, but not as part of the array, and as its own element.
Here is an example of my input I need to transform:
"AL1": {
"0": {
"AllergenCodeMnemonicDescription": {
"1": {
"Text": "ASPIRIN",
"ID": "TEST1"
},
"2": {
"Text": "TYLENOL",
"ID": "TEST2"
}
},
"SetIDAL1": "1"
},
"1": {
"AllergenCodeMnemonicDescription": {
"1": {
"Text": "ADVIL"
}
},
"SetIDAL1": "2"
}
}
}
My current spec I'm using seems to get me pretty close. However, I can't get the arrays up a level in order to remove the 0:1, nor fix the fact that I want the SetIDAL1 value placed inside the newly created array object, instead it makes it's own array object. I've played around with various other options that only lead me further away. Any help for the solution and input/guidance, general "smart ways" to look at this issue would be appreciated.
Unfortunately, I do not have a copy of previous work I tried, which would perform the matching on all groups and map them as expected. I started moving toward matching each individual 0/1 object underneath my input in attempts to see if I could "bury" the SetIDAL properly, to no avail. I really do not want to code for each level, but hoping there's a solution for the "problem at hand" that someone can assist me with.
[
{
"operation": "shift",
"spec": {
"AL1": {
"0": {
"AllergenCodeMnemonicDescription": {
"#": "AL1.[].AllergenCodeMnemonicDescription.[]"
},
"SetIDAL1": "AL1.[].SetIDAL1"
},
"1": {
"AllergenCodeMnemonicDescription": {
"*": "AL1.[].AllergenCodeMnemonicDescription.[]"
},
"SetIDAL1": "AL1.[].SetIDAL1"
}
}
}
}
]
here is the output I am getting. I assume potentially I need yet another shift after this, to bring the "1"/"2" levels "UP again" somehow. But I can't seem to get the SetIDAL1 in the correct place as stated before.
{
"AL1" : [ {
"AllergenCodeMnemonicDescription" : [ {
"1" : {
"Text" : "ASPIRIN",
"ID" : "TEST1"
},
"2" : {
"Text" : "TYLENOL",
"ID" : "TEST2"
}
} ]
}, {
"SetIDAL1" : "1"
}, {
"AllergenCodeMnemonicDescription" : [ {
"Text" : "ADVIL"
} ]
}, {
"SetIDAL1" : "2"
} ]
}
Here is the output I need:
{
"AL1": [
{
"AllergenCodeMnemonicDescription": [
{
"Text": "ASPIRIN",
"ID": "TEST1"
},
{
"Text": "TYLENOL",
"ID": "TEST2"
}
],
"SetIDAL1": "1"
},
{
"AllergenCodeMnemonicDescription": [
{
"Text": "ADVIL"
}
],
"SetIDAL1": "2"
}
]
}
As the indexes start at 1 (not 0) was getting a null on the first element from each Allergen array and had to remove it in the end (not sure if theres a better way to do this), but this specs will do the trick:
[
{
"operation": "shift",
"spec": {
"AL1": {
"*": {
"AllergenCodeMnemonicDescription": {
"*": {
"Text": "AL1.[&3].AllergenCodeMnemonicDescription.[&1].&",
"ID": "AL1.[&3].AllergenCodeMnemonicDescription.[&1].&"
}
},
"SetIDAL1": "AL1.[&1].&"
}
}
}
},
{
"operation": "remove",
"spec": {
"AL1": {
"*": {
"AllergenCodeMnemonicDescription": {
"0": ""
}
}
}
}
}
]

How to perform divide operation in jolt using 'modify-overwrite-beta'

Input,
{"scores": [ 4,2,8,7,5 ] }
Output,
{"FirstElement": 2 } //This is generated by dividing the first element of the array by 2.
Spec,
[{
"operation": "modify-overwrite-beta",
"spec": {
"Avg": "=divide(=firstElement(#(1,scores)),2)"
}
}]
From the above Spec,I am trying to divide the first element of the list by 2 but the output I get is same as the input.
Can't nest "functions" with modify. Have to break it up into two steps.
[
{
"operation": "modify-overwrite-beta",
"spec": {
"firstElement": "=firstElement(#(1,scores))"
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"Avg": "=divide(#(1,firstElement),2)"
}
}
]

How would I use the attribute as input for Value with JOLT?

For a specific function that I am building, I need to parse my JSON and have in some cases the attribute, instead of the value itself, be used as the value for the attribute. But how do I manage that with JOLT?
Let's say this is my input:
{
"Results": [
{
"FirstName": "John",
"LastName": "Doe"
},
{
"FirstName": "Mary",
"LastName": "Joe"
},
{
"FirstName": "Thomas",
"LastName": "Edison"
}
]
}
And this should be the outcome:
{
"Results": [
{
"Name": "FirstName",
"Value": "John"
},
{
"Name": "FirstName",
"Value": "Mary"
},
{
"Name": "FirstName",
"Value": "Thomas"
},
{
"Name": "LastName",
"Value": "Doe"
},
{
"Name": "LastName",
"Value": "Doe"
},
{
"Name": "LastName",
"Value": "Edison"
},
]
}
For those interested.. I'm building a JSON to Excel export functionality in Mendix and it has to be completely dynamic, regardless of the input. To accomplish this, I need an array where each attribute (equal to a column in Excel) has to be it's own object with a column name and a value. If each column data is it's own object, I can simply say "create column for each object with the same "Name". Little bit difficult to explain, but it 'should' work.
Arrays and Jolt, are not the best. Basically there are 3 ways to deal with arrays in Shift.
you explicitly assign data to an array position. Aka foo[0] and foo[1]
you reference a "number" that exists in the input data. Aka foo[&2] and foo[&3]
you "accumulate" data into a list. Aka foo[].
Your input data is array of size 3. Your desired output is an array of size 6. You want this to be flexible and be able to handle variable inputs.
This means option 3. So you have to "fix" / process your data into it "final form", while maintaining the original input Json structure (of a list with 3 items), and then accumulate all the "built" items into a list.
This means that you are buildling a list of lists, and then finally "squashing" it down to a single list.
Spec
[
{
// Step 1 : Pivot the data into parallel lists of keys and values
// maintaining the original outer input list structure.
"operation": "shift",
"spec": {
"Results": {
"*": { // results index
"*": { // FirstName / Lastname
"$": "temp[&2].keys[]",
"#": "temp[&2].values[]"
}
}
}
}
},
{
// Step 2 : Un-pivot the data into the desired
// Name/Value pairs, using the inner array index to
// keep things organized/separated.
"operation": "shift",
"spec": {
"temp": {
"*": { // temp index
"keys": {
"*": "temp[&2].[&].Name"
},
"values": {
"*": "temp[&2].[&].Value"
}
}
}
}
},
{
// Step 3 : Accumulate the "finished" Name/Value pairs
// into the final "one big list" output.
"operation": "shift",
"spec": {
"temp": {
"*": { // outer array
"*": "Results[]"
}
}
}
}
]