Having issue when adding a common value to every elements in array using Jolt - jolt

I am currently using Jolt to work on this input:
{
"banking_account": {
"accounts": [
{
"accountId": "account1"
},
{
"accountId": "account2",
"nickname": "nickname2"
}
]
},
"account_balance": {
"total_value": {
"currency_code": "USD",
"value": "100.00"
},
"balance_accounts": [
{
"id": "id1"
},
{
"id": "id2"
}
]
}
}
And the expected output is:
{
"Data": {
"Accounts": [
{
"AccountId": "account1",
"Account": {
"Identification": [
"id1",
"id2"
]
},
"Currency": "USD"
},
{
"AccountId": "account2",
"NickName": "nickname2",
"Account": {
"Identification": [
"id1",
"id2"
]
},
"Currency": "USD"
}
]
}
}
And here is my current spec:
[
{
"operation": "shift",
"spec": {
"banking_account": {
"accounts": {
"*": {
"accountId": "Data.Accounts.[&1].AccountId",
"nickname": "Data.Accounts.[&1].NickName"
}
}
},
"account_balance": {
"total_value": {
"currency_code": "Data.Accounts.[&1].Currency"
},
"balance_accounts": {
"*": {
"id": "Data.Accounts.[&1].Account.Identification"
}
}
}
}
}
]
And here is my current output:
{
"Data": {
"Accounts": [
{
"AccountId": "account1",
"Account": {
"Identification": "id1"
}
},
{
"AccountId": "account2",
"NickName": "nickname2",
"Account": {
"Identification": "id2"
}
}
]
}
}
So I am having two questions:
Why is the "Currency" value missing? Even if I added something like
"account_balance": {
"total_value": {
"currency_code": "Data.Accounts.[&1].Currency"
}
}
How to map both two balances accounts to both two accounts? Now it seems like an 1->1 mapping; and I wish to have a 2*2 mapping.
Thanks a lot for your help in advance!

You can use this spec for your solution but point 2 is not covered in this and I have added reason for 2nd:
[
{
"operation": "shift",
"spec": {
"banking_account": {
"accounts": {
"*": {
"accountId": "Data.Accounts.[&1].AccountId",
"nickname": "Data.Accounts.[&1].NickName"
}
}
},
"account_balance": {
"total_value": {
"currency_code": "Data.Currency"
},
"balance_accounts": {
"*": {
"id": "Data.Identification"
}
}
}
}
}, {
"operation": "shift",
"spec": {
"Data": {
"Accounts": {
"*": {
"*": "Data.Accounts.[&1].&",
"#(2,Currency)": {
"USD": {
"#USD": "Data.Accounts.[&2].Currency"
}
}
}
},
"Identification": "Data.Identification"
}
}
}
]
& This will answer your two questions :
1 : Why is the "Currency" value missing? Even if I added something like
So you are basically populating a single field element as multiple fields in an array with [&1] which is not possible that's why its not populating.
To do such a case you need to create new elements that will be populating in the Accounts array if you see my spec I am adding a new Current field in every object of Accounts array ->
"Accounts": {
"*": {
"*": "Data.Accounts.[&1].&",
"#(2,Currency)": { //Going 2 levels up to get to currency
"USD": { //If else to check Currency is USD
"#USD": "Data.Accounts.[&2].Currency" //Adding the field in each object of Accounts array.
}
}
}
How to map both two balances accounts to both two accounts? Now it seems like an 1->1 mapping; and I wish to have a 2*2 mapping.
--> This can be achieved in the similar way I have done for 1 but this will again require alot of hardcoding in JOlt.
So my suggestion is to keep both Currency and Identification outside Accounts Array in Data as single object.

Related

Facing issue with JOLT transformation with nested array

I have a JSON input :
{
"id": "Root_ID",
"Item": [
{
"id": "ID_1",
"characteristic": [
{
"name": "char1",
"value": "PRE1"
},
{
"name": "char2",
"value": "2050-01-01"
}
]
},
{
"id": "ID_2",
"characteristic": [
{
"name": "char1",
"value": "PRE2"
},
{
"name": "char2",
"value": "2050-01-02"
}
]
}
]
}
which needs to be converted by using a Jolt transformation spec to the following output :
{
"id": "Root_ID",
"Item": [
{
"id": "ID_1",
"char1": "PRE1",
"char2": "2050-01-01"
},
{
"id": "ID_2",
"char1": "PRE2",
"char2": "2050-01-02"
}
]
}
Currently, I'm using this spec :
[
{
"operation": "shift",
"spec": {
"id": "id",
"Item": {
"*": {
"characteristic": {
"*": {
"name": {
"char1": {
"#(2,value)": "item[#3].char1"
},
"char2": {
"#(2,value)": "item[#3].char2"
}
}
}
}
}
}
}
}
]
which does not produce the desired result.
Can you please help me prepare a correct spec to handle this issue ?
Edit : What if I'd like to get the following JSON result ?
{
"id": "Root_ID",
"Item": [
{
"id": "ID_1",
"char1": "PRE1"
},
{
"id": "ID_2",
"char1": "PRE2",
"char2": "2050-01-02"
}
]
}
You can use the following shift transformation spec in which #value and #name are matched reciprocally such as
[
{
"operation": "shift",
"spec": {
"id": "&",
"Item": {
"*": {
"id": "&2[&1].&",// you can reduce two levels based on the inner identifier 4,3 -> 2,1
"char*": {
"*": {
"#value": "&4[&3].#name" // &4 copies the literal "Item" after going four levels up the tree, [&3] generates array-wise result(array of objects) after going three levels up the tree to reach the level of the indexes of the "Item" array
}
}
}
}
}
}
]
Edit : You can alternatively use the following spec for the case in which you need to return char2 within the all objects but the first :
[
{
"operation": "shift",
"spec": {
"id": "&",
"Item": {
"0": {// stands for the first index
"id": "&2[&1].&",
"char*": {
"*": {
"name": {
"char1": {
"#2,value": "&6[&5].#3,name"
}
}
}
}
},
"*": {
"id": "&2[&1].&",
"char*": {
"*": {
"#value": "&4[&3].#name"
}
}
}
}
}
}
]

JOLT Nested if condition

I have this input JSON:
{
"user": "123456",
"product": "television",
"category": "electronics",
"tag": "summer"
}
And this transformation:
[
{
"operation": "shift",
"spec": {
"product": {
"#(1,product)": "item",
"#(1,user)": {
"#2": "userBias"
}
},
"user": {
"#(1,user)": "user"
},
"category": {
"#category": "rules.[0].name",
"#(1,category)": "rules.[0].values[0]"
},
"tag": {
"rules": "rules",
"#tag": "rules.[1].name",
"#(2,tag)": "rules.[1].values[0]"
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"userBias?": "=toInteger"
}
}
]
Which works fine and produces the following JSON:
{
"item": "television",
"userBias": 2,
"user": "123456",
"rules": [
{
"name": "category",
"values": [
"electronics"
]
},
{
"name": "tag",
"values": [
"summer"
]
}
]
}
If from the input though I delete "category": "electronics" so it becomes:
{
"user": "123456",
"product": "television",
"tag": "summer"
}
Then i get back the following result:
{
"item": "television",
"userBias": 2,
"user": "123456",
"rules": [
null,
{
"name": "tag",
"values": [
"summer"
]
}
]
}
The problem with the above is that it contains a null element inside the array and I do not know how to get rid of it. I have tried with recursivelySquashNulls but it does not work.
Also basically what am looking for is if both category and tag exist then tag should go to rules[1] if only tag exists then tag should go to rules[0].
Thanks in advance,
giannis
Because you specify tag and category elements individually. Rather, prefer putting them into the category rest by combining them under asterisked key notation such as
[
{
"operation": "shift",
"spec": {
"product": {
"#(1,product)": "item",
"#(1,user)": {
"#2": "userBias"
}
},
"user": {
"#(1,user)": "user"
},
"*": {
"$": "r[0].&.name",
"#(1,&)": "r[0].&.values[]"
}
}
},
{
"operation": "shift",
"spec": {
"*": "&",
"r": {
"*": { "*": "rules" }
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"userBias?": "=toInteger"
}
}
]
Result1 :
Result2(without "category": "electronics" pair for the Input) :

Add array inside object with same key in jolt spec

I would like to move the recommendations array by row_id key inside the investors with the same row_id
Original Json
{
"investors": [
{
"row_id": 1,
"name": "AAAA"
},
{
"row_id": 2,
"name": "BBBB"
}
],
"recommendations": [
{
"row_id": "1",
"title": "ABC"
},
{
"row_id": "2",
"title": "CDE"
}
]
}
I've tried a lot of specs at https://jolt-demo.appspot.com with no success
Specs tried...
[{
"operation": "shift",
"spec": {
"investors": {
"*": "investors[]"
},
"recommendations": {
"#": "recommendations[]"
}
}
}]
Desired Json
{
"investors": [
{
"row_id": 1,
"name": "AAAA",
"recommendations":[{
"row_id": "1",
"title": "ABC"
}]
},
{
"row_id": 2,
"name": "BBBB",
"recommendations":[{
"row_id": "2",
"title": "CDE"
}]
}
]
}
This can be done in two stage shift
First shift groups everything based on row_id.
(I'd suggest running the first shift of its own to see what the output is)
Second shift uses that grouped output and formats results.
[
{
"operation": "shift",
"spec": {
"*": {
"*": {
"row_id": {
"*": {
"#2": "&.&4"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"investors": "investors.[#2]",
"recommendations": "investors.[#2].recommendations[]"
}
}
}
]

Need JOLT spec file for transfer of complex JSON

I have a complex JSON object (I've simplified it for this example) that I cannot figure out the JOLT transform JSON for. Does anybody have any ideas of what the JOLT spec file should be?
Original JSON
[
{
"date": {
"isoDate": "2019-03-22"
},
"application": {
"name": "SiebelProject"
},
"applicationResults": [
{
"reference": {
"name": "Number of Code Lines"
},
"result": {
"value": 44501
}
},
{
"reference": {
"name": "Transferability"
},
"result": {
"grade": 3.1889542208002064
}
}
]
},
{
"date": {
"isoDate": "2019-03-21"
},
"application": {
"name": "SiebelProject"
},
"applicationResults": [
{
"reference": {
"name": "Number of Code Lines"
},
"result": {
"value": 45000
}
},
{
"reference": {
"name": "Transferability"
},
"result": {
"grade": 3.8
}
}
]
}
]
Desired JSON after transformation and sorting by "Name" ASC, "Date" DESC
[
{
"Name": "SiebelProject",
"Date": "2019-03-22",
"Number of Code Lines": 44501,
"Transferability" : 3.1889542208002064
},
{
"Name": "SiebelProject",
"Date": "2019-03-21",
"Number of Code Lines": 45000,
"Transferability" : 3.8
}
]
I couldn't find a way to do the sort (I'm not even sure you can sort descending in JOLT) but here's a spec to do the transform:
[
{
"operation": "shift",
"spec": {
"*": {
"date": {
"isoDate": "[#3].Date"
},
"application": {
"name": "[#3].Name"
},
"applicationResults": {
"*": {
"reference": {
"name": {
"Number of Code Lines": {
"#(3,result.value)": "[#7].Number of Code Lines"
},
"Transferability": {
"#(3,result.grade)": "[#7].Transferability"
}
}
}
}
}
}
}
}
]
After that there are some tools (like jq I think) that could do the sort.

Combining two arrays and transformation using Jolt

I am having a tough time using Jolt mapping trying to transform the input to the necessary form
Input JSON
{
"data": [
{
"name": "Alcohol",
"collection_id": 123,
"properties": [
{
"name": "Tax",
"property_id": "00001"
},
{
"name": "Expenditure",
"property_id": "00002"
}
],
"attributes": [
{
"name": "alcohol_tax",
"attribute_id": "00011"
},
{
"name": "alcohol_expenditure",
"attribute_id": "00022"
}
]
}
]
}
Output JSON
[
{
"name": "Alcohol",
"collection_id": 123,
"details": [{
"property_name": "Tax",
"property_id": "00001",
"attribute_id": "00011"
},
{
"property_name": "Expenditure",
"property_id": "00002",
"attribute_id": "00022"
}
]
}
]
I have tried a couple of ways to combine the arrays using a few rules but with little success.
One of the rules
[{
"operation": "shift",
"spec": {
"data": {
"*": {
"name": "&1.name",
"collection_id": "&1.collection_id",
"attributes": {
"*": {
"attribute_id": "&1.attribute_id[]"
}
},
"properties": {
"*": {
"name": "&1.myname[]",
"property_id": "&1.property_id[]"
}
}
}
}
}
}]
is adding all the attributes and properties to all the collections.I do not know why this happens as I thought &1.property_id[] would only add items in that particular collection to the array and not all collections. Any help/clues on why this is happening would be truly appreciated.
See solution below:
[0] creates the wrapping array
[&1] uses the position of the respective arrays so the results are combined in details the important part is wrapping square brackets so its treated as array rather than literal.
[
{
"operation": "shift",
"spec": {
"data": {
"*": {
"name": "[0].name",
"collection_id": "[0].collection_id",
"attributes": {
"*": {
"attribute_id": "[0].details.[&1].attribute_id"
}
},
"properties": {
"*": {
"name": "[0].details.[&1].name",
"property_id": "[0].details.[&1].property_id"
}
}
}
}
}
}
]
Produces the following:
[
{
"name": "Alcohol",
"collection_id": 123,
"details": [
{
"attribute_id": "00011",
"name": "Tax",
"property_id": "00001"
},
{
"attribute_id": "00022",
"name": "Expenditure",
"property_id": "00002"
}
]
}
]