Reputation: 21
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"
}
}
]
Upvotes: 2
Views: 651
Reputation: 65408
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.
Upvotes: 1