I trying to apply JOLT transformation to convert one JSON structure into another. The JOLT spec I came up with does not distribute parent fields to child as I want and is explained in the example below. Could you please help with the mistake I'm doing in the spec?
My input JSON
{
"numberOfBlocks": 2,
"signatoryBlocks": [
{
"block": [
{
"role": "abcd"
},
{
"order": "1"
},
{
"signatureProviderName": "universalsignaturepen_opentrust_hash_tsp"
},
{
"signatories": [
{
"email": "joe.smith#abcd.com",
"name": "Joe Smith",
"initials": "JS",
"capacity": "Authorised Signatory",
"company": "abcd AG",
"oneTimePassword": "test_joe",
"sms": "1234"
},
{
"email": "jane.doe#abcd.com",
"name": "Jane Doe",
"initials": "JD",
"capacity": "Director",
"company": "abcd AG",
"oneTimePassword": "test_jane",
"sms": "4567"
}
]
}
]
},
{
"block": [
{
"role": "Signer 2"
},
{
"order": "1"
},
{
"signatureProviderName": "universalsignaturepen_opentrust_hash_tsp"
},
{
"signatories": [
{
"email": "rachel.smith#abcd.com",
"name": "Rachel Smith",
"initials": "RS",
"capacity": "Authorised Signatory",
"company": "abcd AG",
"oneTimePassword": "test_rachel",
"sms": ""
},
{
"email": "joe.bloggs#abcd.com",
"name": "Joe Bloggs",
"initials": "JB",
"capacity": "Authorised Signatory",
"company": "abcd AG",
"oneTimePassword": "test_joe",
"sms": "111"
}
]
}
]
}
]
}
My JOLT spec
[
{
"operation": "shift",
"spec": {
"#3186": "entityId",
"#160": "entityTypeId",
"#1007": "clientId",
"*": ["rawData.&0", "formatedData.&0"]
}
},
{
"operation": "shift",
"spec": {
"*": "&0",
"formatedData": {
"signatoryBlocks": {
"*": {
"block": {
"3": {
"signatories": {
"*": {
"#3": {
"0": {
"role": "formatedData.[#8].roleGroupName"
},
"1": {
"order": "formatedData.[#8].order"
},
"2": {
"signatureProviderName": "formatedData.[#8].signatureProviderName"
}
},
"*": "formatedData.[#6].userDetails[#2].&0"
}
}
}
}
}
}
}
}
},
{
"operation": "cardinality",
"spec": {
"formatedData": {
"*": {
"roleGroupName": "ONE",
"order": "ONE",
"signatureProviderName": "ONE"
}
}
}
}
]
Output I am getting using my JOLT spec
{
"entityId": "3186",
"entityTypeId": "160",
"clientId": "1007",
"rawData": {
"numberOfBlocks": 2,
"signatoryBlocks": [
{
"block": [
{
"role": "abcd"
},
{
"order": "1"
},
{
"signatureProviderName": "universalsignaturepen_opentrust_hash_tsp"
},
{
"signatories": [
{
"email": "joe.smith#abcd.com",
"name": "Joe Smith",
"initials": "JS",
"capacity": "Authorised Signatory",
"company": "abcd AG",
"oneTimePassword": "test_joe",
"sms": "1234"
},
{
"email": "jane.doe#abcd.com",
"name": "Jane Doe",
"initials": "JD",
"capacity": "Director",
"company": "abcd AG",
"oneTimePassword": "test_jane",
"sms": "4567"
}
]
}
]
},
{
"block": [
{
"role": "Signer 2"
},
{
"order": "1"
},
{
"signatureProviderName": "universalsignaturepen_opentrust_hash_tsp"
},
{
"signatories": [
{
"email": "rachel.smith#abcd.com",
"name": "Rachel Smith",
"initials": "RS",
"capacity": "Authorised Signatory",
"company": "abcd AG",
"oneTimePassword": "test_rachel",
"sms": ""
},
{
"email": "joe.bloggs#abcd.com",
"name": "Joe Bloggs",
"initials": "JB",
"capacity": "Authorised Signatory",
"company": "abcd AG",
"oneTimePassword": "test_joe",
"sms": "111"
}
]
}
]
}
]
},
"formatedData": [
{
"roleGroupName": "abcd",
"order": "1",
"signatureProviderName": "universalsignaturepen_opentrust_hash_tsp",
"userDetails": [
{
"email": "joe.smith#abcd.com",
"name": "Joe Smith",
"initials": "JS",
"capacity": "Authorised Signatory",
"company": "abcd AG",
"oneTimePassword": "test_joe",
"sms": "1234"
},
{
"email": "jane.doe#abcd.com",
"name": "Jane Doe",
"initials": "JD",
"capacity": "Director",
"company": "abcd AG",
"oneTimePassword": "test_jane",
"sms": "4567"
}
]
},
{
"roleGroupName": "Signer 2",
"order": "1",
"signatureProviderName": "universalsignaturepen_opentrust_hash_tsp",
"userDetails": [
{
"email": "rachel.smith#abcd.com",
"name": "Rachel Smith",
"initials": "RS",
"capacity": "Authorised Signatory",
"company": "abcd AG",
"oneTimePassword": "test_rachel",
"sms": ""
},
{
"email": "joe.bloggs#abcd.com",
"name": "Joe Bloggs",
"initials": "JB",
"capacity": "Authorised Signatory",
"company": "abcd AG",
"oneTimePassword": "test_joe",
"sms": "111"
}
]
}
]
}
Output I want
{
"entityId": 3186,
"entityTypeId": 160,
"clientId": 1007,
"rawData": "complete_body_of_input_JSON_here",
"formatedData": [
{
"roleGroupName": "abcd",
"order": "1",
"signatureProvider": "universalsignaturepen_opentrust_hash_tsp",
"userDetails": [
{
"email": "joe.smith#abcd.com",
"name": "Joe Smith",
"initials": "JS",
"capacity": "Authorised Signatory",
"company": "abcd AG",
"oneTimePassword": "test_joe",
"sms": "1234"
}
]
},
{
"roleGroupName": "abcd",
"order": "1",
"signatureProvider": "universalsignaturepen_opentrust_hash_tsp",
"userDetails": [
{
"email": "jane.doe#abcd.com",
"name": "Jane Doe",
"initials": "JD",
"capacity": "Director",
"company": "abcd AG",
"oneTimePassword": "test_jane",
"sms": "4567"
}
]
},
{
"roleGroupName": "Signer 2",
"order": "1",
"signatureProvider": "universalsignaturepen_opentrust_hash_tsp",
"userDetails": [
{
"email": "rachel.smith#abcd.com",
"name": "Rachel Smith",
"initials": "RS",
"capacity": "Authorised Signatory",
"company": "abcd AG",
"oneTimePassword": "test_rachel",
"sms": ""
}
]
},
{
"roleGroupName": "Signer 2",
"order": "1",
"signatureProvider": "universalsignaturepen_opentrust_hash_tsp",
"userDetails": [
{
"email": "joe.bloggs#abcd.com",
"name": "Joe Bloggs",
"initials": "JB",
"capacity": "Authorised Signatory",
"company": "abcd AG",
"oneTimePassword": "test_joe",
"sms": "111"
}
]
}
]
}
What am I doing wrong?
Here is the answer
[
{
"operation": "shift",
"spec": {
"#3186": "entityId",
"#160": "entityTypeId",
"#1007": "clientId",
"*": ["rawData.&0","formatedData.&0"]
}
},
{
"operation": "shift",
"spec": {
"*": "&0",
"formatedData": {
"signatoryBlocks": {
"*": {
"block": {
"3": {
"signatories": {
"*": {
"#3": {
"0": {
"role": "formatedData.[#8].[#6].[#4].roleGroupName"
},
"1": {
"order": "formatedData.[#8].[#6].[#4].order"
},
"2": {
"signatureProviderName": "formatedData.[#8].[#6].[#4].signatureProviderName"
}
},
"*": "formatedData.[#6].[#4].[#2].userDetails.&0"
}
}
}
}
}
}
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"entityId": "=toInteger",
"entityTypeId": "=toInteger",
"clientId": "=toInteger"
}
},
{
"operation": "shift",
"spec": {
"*": "&0",
"formatedData": {
"*": {
"*": {
"*": "formatedData"
}
}
}
}
}
]
Related
I want to use Jolt Shift to transform below input to a desire output. The input have two level array nested. Please help me out if you have a solution for this. Thanks in advance.
Input:
{
"P": {
"type": "manager",
"metadata": {
"id": "mgr1"
},
"properties": {
"firstName": "managerFirstName",
"lastName": "managerLastName",
"employmentId": "employmentId"
},
"S": [
{
"type": "employee",
"metadata": {
"id": "empl1"
},
"properties": {
"last": "employeeOneLastName",
"first": "employeeOneFirstName"
},
"S": [
{
"type": "address",
"metadata": {
"identifier": "addr1"
},
"properties": {
"city": "addressOneCity",
"street": "addressOneStreet"
}
},
{
"type": "address",
"metadata": {
"id": "addr2"
},
"properties": {
"city": "addressTwoCity",
"street": "addressTwoStreet"
}
}
]
},
{
"type": "employee",
"metadata": {
"id": "empl2"
},
"properties": {
"last": "employeeTwoLastName",
"first": "employeeTwoFirstName"
},
"S": [
{
"type": "address",
"metadata": {
"id": "addr3"
},
"properties": {
"city": "addressThreeCity",
"street": "addressThreeStreet"
}
},
{
"type": "address",
"metadata": {
"id": "addr4"
},
"properties": {
"city": "addressFourCity",
"street": "addressFourStreet"
}
},
{
"type": "address",
"metadata": {
"id": "addr5"
},
"properties": {
"city": "addressFiveCity",
"street": "addressFiveStreet"
}
}
]
},
{
"type": "officeinfo",
"metadata": {
"id": "office1"
},
"properties": {
"country": "myCountry",
"city": "myCity",
"employmentId": "employmentId"
}
}
]
}
}
Desired Output:
{
"manager": {
"type": "manager",
"firstName": "managerFirstName",
"lastName": "managerLastName",
"employmentId": "employmentId",
"employee": [
{
"type": "employee",
"lastName": "employeeOneLastName",
"firstName": "employeeOneFirstName",
"address": [
{
"type": "address",
"city": "addressOneCity",
"street": "addressOneStreet"
},
{
"type": "address",
"city": "addressTwoCity",
"street": "addressTwoStreet"
}
]
},
{
"address": [
{
"city": "addressTwoCity",
"street": "addressThreeStreet",
"type": "address"
},
{
"type": "address",
"city": "addressFourCity",
"street": "addressFourStreet"
},
{
"city": "addressFiveCity",
"street": "addressFiveStreet",
"type": "address"
}
],
"type": "employee",
"lastName": "employeeTwoLastName",
"firstName": "employeeTwoFirstName"
}
],
"office": {
"type": "officeinfo",
"country": "myCountry",
"city": "myCity",
"employmentId": "employmentId"
}
}
}
Here is my spec which is not working as desired. The addresses associated with the employee is not correct. Notice the employeeOne should have both address One and Two, and the employeeTwo should have the address of Three, Four, and Five.
[
{
"operation": "shift",
"spec": {
"P": {
"type": "manager.&",
"properties": {
"firstName": "manager.firstName",
"lastName": "manager.lastName",
"employmentId": "manager.employmentId"
},
"S": {
"*": {
"type": {
"officeinfo": {
"$": "manager.office.type"
},
"employee": {
"$": "manager.employee[&3].type"
}
},
"*": {
"last": "manager.employee[&2].lastName",
"first": "manager.employee[&2].firstName",
"country": "manager.office.country",
"city": "manager.office.city",
"employmentId": "manager.office.employmentId"
},
"S": {
"*": {
"type": "manager.employee[&3].address[&1].type",
"*": {
"city": "manager.employee[&2].address[&4].city",
"street": "manager.employee[&2].address[&4].street"
}
}
}
}
}
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"*": "=recursivelySquashNulls"
}
}
]
The trick is using #(<int>,type) at appropriate locations in order to separate the sub-objects and sub-arrays properly such as
[
{
"operation": "shift",
"spec": {
"*": {
"type": "#(1,type).&",
"prop*": {
"*": "#(2,type).&"
},
"S": {
"*": {
"type": {
"employee": {
"#1": "#(5,type).&1[&3].&2" // count how many ":" and/or "{" chars should be traversed while going up the tree in order to reach the level of "type" to determine the <int>(it's 5 in this case)
},
"*info": {
"#1": "#(5,type).&(1,1).&2" // "&(1,1)" represents the piece where "*" stays, so it's "office" in this case
}
},
"prop*": {
"*st": "#(4,type).#(2,type)[&2].&Name"
},
"S": {
"*": {
"prop*": {
"#(1,type)": "#(6,type).#(4,type)[&4].#(2,type)[&2].type",
"*": "#(6,type).#(4,type)[&4].#(2,type)[&2].&"
}
}
}
}
}
}
}
},
{
// stands for nothing but sorting
"operation": "shift",
"spec": {
"*": {
"type": "&1.&",
"firstName": "&1.&",
"lastName": "&1.&",
"employmentId": "&1.&",
"employee": "&1.&",
"offi*": "&1.&"
}
}
}
]
Note that, no need to repeat the key names at right-hand-side of the key-value pairs in order to replicate them, but just use ampersands. Btw, the second shift transformation is just added to provide getting the desired order, eg. might be removed without affecting the currently handled transformation.
This is my first time to use JoltTransformationJson, so I have limited knowledge and experience on that. Please help me with this complicated project.
Request:
when the payment.code <> "paid", I have to do the following two things for the file.
to change the payment.code ="denied" and payment.text ="denied"
to add a JSON object to item.ADJ
When the payment.code =="paid", don't need to change anything.
Input :
{
"resourceType": "E",
"id": "11",
"identifier": [
{
"type": {
"coding": [
{
"system": "sys1",
"code": "aaa"
}
]
},
"value": "212"
},
{
"type": {
"coding": [
{
"system": "sys2",
"code": "RRR"
}
]
},
"value": "367"
}
],
"status": "active",
"created": "2021-08-05T02:43:48+00:00",
"outcome": "complete",
"item": [
{
"sequence": 1,
"product": {
"coding": [
{
"system": "example",
"code": "abc",
"display": "ABC"
}
],
"text": "ABC"
},
"servicedDate": "2021-08-04",
"quantity": {
"value": 60
},
"ADJ": [
{
"category": {
"coding": [
{
"system": "code1",
"code": "code1",
"display": "CODE1"
}
],
"text": "CODE1"
},
"amount": {
"value": 46.45,
"currency": "USD"
}
},
{
"category": {
"coding": [
{
"system": "code2",
"code": "code2",
"display": "CODE2"
}
],
"text": "CODE2"
},
"amount": {
"value": 12.04,
"currency": "USD"
}
}
]
}
],
"payment": {
"type": {
"coding": [
{
"system": "http://payment.com",
"code": "reversed/cancelled"
}
],
"text": "cancelled"
}
}
}
My Expected Output :
{
"resourceType": "E",
"id": "11",
"identifier": [
{
"type": {
"coding": [
{
"system": "sys1",
"code": "aaa"
}
]
},
"value": "212"
},
{
"type": {
"coding": [
{
"system": "sys2",
"code": "RRR"
}
]
},
"value": "367"
}
],
"status": "active",
"created": "2021-08-05T02:43:48+00:00",
"outcome": "complete",
"item": [
{
"sequence": 1,
"product": {
"coding": [
{
"system": "example",
"code": "abc",
"display": "ABC"
}
],
"text": "ABC"
},
"servicedDate": "2021-08-04",
"quantity": {
"value": 60
},
"ADJ": [
{
"category": {
"coding": [
{
"system": "code1",
"code": "code1",
"display": "CODE1"
}
],
"text": "CODE1"
},
"amount": {
"value": 46.45,
"currency": "USD"
}
},
{
"category": {
"coding": [
{
"system": "code2",
"code": "code2",
"display": "CODE2"
}
],
"text": "CODE2"
},
"amount": {
"value": 12.04,
"currency": "USD"
}
},
{// new object I want to insert into
"category": {
"coding": [
{
"system": "sys_denail",
"code": "denialreason"
}
],
"reason": {
"coding": [
{
"system": "https://example.com",
"code": "A1"
}
],
"text": "unknown"
}}
}
]
}
],
"payment": {
"type": {
"coding": [
{
"system": "http://payment.com",
"code": "denied" //change the value to denied
}
],
"text": "denied" //change the value to denied
}
}
}
Edit : I've tried to answer the second case by myself to be evaluated after the first case is answered
Welcome to SO, please ask minimal and reproducible questions, and show your effort tried for the future.
What you need is to use a conditional logic along with placeholder values with ampersand symbols depending on the levels of each key name within the tree.
I have partially answered, which will handle the bottom part of your question. Indeed the logic for the rest(inserting an object to the array will be similiar)
So, consider having a look at the following solution
[
{
"operation": "shift",
"spec": {
"*": "&",
"payment": {
"type": {
"coding": {
"*": {
"*": "&4.&3.&2[&1].&",
"code": {
"paid": {
"#1": "&6.&5.&4[&3].&2",
"#(4,text)": "&6.text"
},
"*": {
"#denied": "&6.&5.&4[&3].code",
"#(4,text)": {
"#denied": "&6.text"
}
}
}
}
}
}
}
}
}
]
Edit(for your own answer related to adding an object):
your current idea of using shift after default transformation spec is pretty good, you can rephrase like
[
{
"operation": "default",
"spec": {
"temp_deny": {
"denialreason": {
"category": {
"coding": [
{
"system": "sys_denail",
"code": "denialreason"
}
],
"reason": {
"coding": [
{
"system": "https://example.com",
"code": "A1"
}
],
"text": "unknown"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": "&",
"item": {
"*": {
"*": "&2[&1].&",
"ADJ": {
"#": "&3[&2].&",
"#(4,temp_deny)": "&3[&2].&"
}
}
}
}
}
]
Original JSON message:
[
{
"correlationId": "12345",
"payloadFormat": "Money",
"payload": {
"stateName": "TX",
"location": "south",
"name": "Dallas",
"pop": "2M"
}
},
{
"correlationId": "ed1e3",
"payloadFormat": "Cash",
"payload": {
"stateName": "CA",
"location": "west",
"name": "LosAngeles",
"pop": "4M"
}
}
]
Output should be in below format:
[
{
"correlationId": "12345",
"payloadFormat": "Money",
"payload": {
"California": "TX",
"MontGomery": "south",
"City": "Dallas",
"ID": "2M"
}
},
{
"correlationId": "ed1e3",
"payloadFormat": "Cash",
"payload": {
"California": "CA",
"MontGomery": "west",
"City": "LosAngeles",
"ID": "4M"
}
}
]
Check this spec,
[
{
"operation": "shift",
"spec": {
"*": {
"correlationId": "[&1].correlationId",
"payloadFormat": "[&1].payloadFormat",
"payload": {
"stateName": "[&2].payload.California",
"location": "[&2].payload.MontGomery",
"name": "[&2].payload.City",
"pop": "[&2].payload.ID"
}
}
}
}
]
just checking before i build the wheel
I need a hackjob to present an api endpoint in a database. It doesn't need to do anything fancy, just convert what the rest api spits out into a single column of json. A new row at each iteration at the root/top level would be nice but a single varchar or whatever would be ok too
Does an ODBC wrapper exist out there anywhere? Googling just brings up hits for doing the opposite (exposing databases as an api). I'm not interested in the simba etc paid stuff. The consumer is SQL server so i can just use xp_cmdshell with curl as a last resort
so for instance the output of this : http://jsonapiplayground.reyesoft.com/v2/authors could come out as a table like so (a row for each author)
|data |
---------------------------------------------------
|{
"type": "authors",
"id": "1",
"attributes": {
"name": "Madge Mohr DVM 2",
"date_of_birth": "1977-08-21",
"date_of_death": "2009-09-14"
},
"relationships": {
"photos": {
"data": []
},
"books": {
"data": [
{
"type": "books",
"id": "41"
}
]
}
},
"links": {
"self": "/v2/authors/1"
}
} |
---------------------------------------------------
|{
"type": "authors",
"id": "3",
"attributes": {
"name": "Zelma Ortiz DDS",
"date_of_birth": "1992-09-06",
"date_of_death": "2000-12-19"
},
"relationships": {
"photos": {
"data": [
{
"type": "photos",
"id": "3"
}
]
},
"books": {
"data": [
{
"type": "books",
"id": "36"
},
{
"type": "books",
"id": "48"
}
]
}
},
"links": {
"self": "/v2/authors/3"
}
}|
----------
|{
"type": "authors",
"id": "4",
"attributes": {
"name": "Fermin Barrows Sr.",
"date_of_birth": "1991-03-18",
"date_of_death": "1975-11-07"
},
"relationships": {
"photos": {
"data": [
{
"type": "photos",
"id": "4"
}
]
},
"books": {
"data": [
{
"type": "books",
"id": "1"
},
{
"type": "books",
"id": "26"
},
{
"type": "books",
"id": "44"
},
{
"type": "books",
"id": "46"
}
]
}
},
"links": {
"self": "/v2/authors/4"
}
}|
----------
|{
"type": "authors",
"id": "5",
"attributes": {
"name": "Terry Durgan",
"date_of_birth": "2011-03-06",
"date_of_death": "2017-04-13"
},
"relationships": {
"photos": {
"data": [
{
"type": "photos",
"id": "5"
}
]
},
"books": {
"data": [
{
"type": "books",
"id": "6"
},
{
"type": "books",
"id": "16"
},
{
"type": "books",
"id": "50"
}
]
}
},
"links": {
"self": "/v2/authors/5"
}
}|
----------
|{
"type": "authors",
"id": "6",
"attributes": {
"name": "Annalise Walsh",
"date_of_birth": "2004-11-27",
"date_of_death": "1997-07-20"
},
"relationships": {
"photos": {
"data": [
{
"type": "photos",
"id": "6"
}
]
},
"books": {
"data": [
{
"type": "books",
"id": "4"
},
{
"type": "books",
"id": "5"
},
{
"type": "books",
"id": "21"
}
]
}
},
"links": {
"self": "/v2/authors/6"
}
}|
---------
I want to get the hierarchy of a JSON using a value. For example: In below JSON for value "Medical record number" , the desired information is "resource->identifier->type->coding->display" . IS their any inbuilt function to do so.
The one way to look for opening and ending braces to locate nodes. Any other efficient way ?
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"fullUrl": "Patient/996-756-495-101",
"resource": {
"resourceType": "Patient",
"id": "996-756-495-101",
"identifier": [
{
"type": {
"coding": [
{
"system": "http://hl7.org/fhir/v2/0203",
"code": "MR",
"display": "Medical record number"
}
]
},
"system": "https://www.lumc.nl",
"value": "996-756-495-101"
}
],
"name": [
{
"use": "usual",
"family": [
"Levin_4"
],
"given": [
"Henry_4"
]
}
],
"gender": "male",
"birthDate": "1932-09-24",
"maritalStatus": {
"coding": [
{}
]
},
"managingOrganization": {
"reference": "Organization/12"
}
},
"request": {
"method": "POST",
"url": "Patient",
"ifNoneExist": "identifier=https://www.lumc.nl|996-756-495-101"
}
},
{
"fullUrl": "FamilyMemberHistory/d42ebf70-5c89-11db-b0de-0800200c9a66",
"resource": {
"resourceType": "FamilyMemberHistory",
"id": "d42ebf70-5c89-11db-b0de-0800200c9a66",
"patient": {
"reference": "Patient/996-756-495-101"
},
"status": "Partial",
"relationship": {
"coding": [
{
"system": "http://hl7.org/fhir/ValueSet/v3-FamilyMember",
"code": "FTH",
"display": "Father"
}
],
"text": "Father"
},
"gender": "male",
"bornDate": "1912",
"deceasedBoolean": true
},
"request": {
"method": "POST",
"url": "FamilyMemberHistory"
}
},
{
"fullUrl": "FamilyMemberHistory/a13c6160-5c8b-11db-b0de-0800200c9a66",
"resource": {
"resourceType": "FamilyMemberHistory",
"id": "a13c6160-5c8b-11db-b0de-0800200c9a66",
"patient": {
"reference": "Patient/996-756-495-101"
},
"status": "Partial",
"relationship": {
"coding": [
{
"system": "http://hl7.org/fhir/ValueSet/v3-FamilyMember",
"code": "MTH",
"display": "Mother"
}
],
"text": "Mother"
},
"gender": "female",
"bornDate": "1912",
"deceasedBoolean": false
},
"request": {
"method": "POST",
"url": "FamilyMemberHistory"
}
}
]
}