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.
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"
}
}
}
}
}
]
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].&"
}
}
}
}
}
]
I just started learning jolt transformations.I found this scenario. The spec also is posted, but I am trying to understand the spec, and confused with the levels of the fields using "&".
From the below spec:
I am confused with this syntax "name": "state[&3].cities[&1].cityname".
Why "name": "state[&2].cities[&1].cityname" doesn't give any output? As per my understanding the level of state for city name is &2. Can someone please try to explain why &3 is used.
Input Json:
{
"country": "usa",
"state": [
{
"stateName": "TX",
"location": "south",
"cities": [
{
"name": "Austin",
"pop": "1M"
},
{
"name": "Dallas",
"pop": "2M"
}
]
},
{
"stateName": "CA",
"location": "west",
"cities": [
{
"name": "SanFran",
"pop": "3M"
},
{
"name": "LosAngeles",
"pop": "4M"
}
]
}
]
}
Expected Output:
{
"country": "usa",
"state": [
{
"stateName": "TX",
"locatedIn": "south", // name change here
"cities": [
{
"cityname": "Austin", // name change here
"citypopulation": "1M" // name change here
},
{
"cityname": "Dallas",
"citypopulation": "2M"
}
]
},
{
"stateName": "CA",
"locatedIn": "west",
"cities": [
{
"cityname": "SanFran",
"pop": "3M"
},
{
"cityname": "LosAngeles",
"citypopulation": "4M"
}
]
}
]
}
Spec:
[
{
"operation": "shift",
"spec": {
"country": "country",
"state": {
"*": { // state array index
"stateName": "state[&1].stateName",
"location": "state[&1].location",
"cities": {
"*": { // city array index
"name": "state[&3].cities[&1].cityname",
"pop": "state[&3].cities[&1].citypopualtion"
}
}
}
}
}
}
]
{
"operation": "shift",
"spec": {
"country": "country",
"state": {
"*": { // state array index <- level 3
"stateName": "state[&1].stateName",
"location": "state[&1].location",
"cities": { <- level 2
"*": { // city array index <- level 1
"name": "state[&3].cities[&1].cityname", <- level 0
"pop": "state[&3].cities[&1].citypopualtion"
}
}
}
}
}
}
You are actually retrieving the index, that is represented by the "*". If you use &2 you are getting the cities and siblings level but you dont want to access those attributes. So during transformation it will actually end up being something like state[state_index].cities[city_index].cityname
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"
}
}
]
}