I am news to jolt json transformation. So looking for help in transforming nested json having list of values to nested json with list as following.
Input json
{
"userData": [
{
"userId": "1",
"age": "20",
"firstName": "firstname1",
"lastname": "lastname1",
"zipCode": "zipcode1",
"street": "street1",
"city": "city1",
"country": "country",
"gender": "gender1",
"grade": "grade1",
"birthday": "birthday1"
},
{
"userId": "2",
"age": "25",
"firstName": "firstname2",
"lastname": "lastname2",
"zipCode": "zipcode2",
"street": "street2",
"city": "city2",
"country": "country2",
"gender": "gender2",
"grade": "grade2",
"birthday": "birthday2"
}
]
}
Jolt Specification
[
{
"operation": "shift",
"spec": {
"userData": {
"*": {
"userId": "data.[&1].ID",
"*": "data.[&1].&",
"zipCode": {
"#custom-field1": "adr_&1.property",
"@": "adr_&.value"
},
"street": {
"#custom-field2": "adr_&1.property",
"@": "adr_&.value"
},
"city": {
"#custom-field3": "adr_&1.property",
"@": "adr_&.value"
},
"country": {
"#custom-field4": "adr_&1.property",
"@": "adr_&.value"
}
}
}
}
}
]
Output
{
"data" : [ {
"ID" : "1",
"age" : "20",
"firstName" : "firstname1",
"lastname" : "lastname1",
"gender" : "gender1",
"grade" : "grade1",
"birthday" : "birthday1"
}, {
"ID" : "2",
"age" : "25",
"firstName" : "firstname2",
"lastname" : "lastname2",
"gender" : "gender2",
"grade" : "grade2",
"birthday" : "birthday2"
} ],
"adr_zipCode" : {
"property" : [ "custom-field1", "custom-field1" ],
"value" : [ "zipcode1", "zipcode2" ]
},
"adr_street" : {
"property" : [ "custom-field2", "custom-field2" ],
"value" : [ "street1", "street2" ]
},
"adr_city" : {
"property" : [ "custom-field3", "custom-field3" ],
"value" : [ "city1", "city2" ]
},
"adr_country" : {
"property" : [ "custom-field4", "custom-field4" ],
"value" : [ "country", "country2" ]
}
}
Expected json
{
"data": [
{
"ID": "1",
"age": "20",
"firstName": "firstname1",
"lastname": "lastname1",
"gender": "gender1",
"grade": "grade1",
"birthday": "birthday1",
"address": [
{
"property": "custom-field1",
"value": "zipcode1"
},
{
"property": "custom-field2",
"value": "street1"
},
{
"property": "custom-field3",
"value": "city1"
},
{
"property": "custom-field4",
"value": "country"
}
]
},
{
"ID": "2",
"age": "25",
"firstName": "firstname2",
"lastname": "lastname2",
"gender": "gender2",
"grade": "grade2",
"birthday": "birthday2",
"address": [
{
"property": "custom-field1",
"value": "zipcode2"
},
{
"property": "custom-field2",
"value": "street2"
},
{
"property": "custom-field3",
"value": "city2"
},
{
"property": "custom-field4",
"value": "country2"
}
]
}
]
}
CodePudding user response:
You can use individual value
arrays of their indexes to be used within the upcoming specs with a tricky zeroth member which will be removed later, after been used such as
[
{
"operation": "shift",
"spec": {
"userData": {
"*": {
"userId": "data[&1].ID",
"@(0,age)": "data[&1].age", //multiplexed this attribute in order to make it the zeroth index, which will be removed within the upcoming specs, for the "address" array at the same time, as indexing starts from zero ...
"*": "data[&1].&",
"a*|z*|s*|c*": {//separating "zipCode", "street", "city", "country" attributes from the others while using "a*" for "age" is tricky, temporarily
"@": "data[&2].value"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"data": {
"*": {
"*": "&2[&1].&",
"value": {
"*": {
"#property": "&4[&3].address[&1].custom-field&1",
"@(2,value[&])": "&4[&3].address[&1].value"
}
}
}
}
}
},
{ // the attributes are written individually to keep the desired sorting
"operation": "shift",
"spec": {
"data": {
"*": {
"ID": "&2[&1].&",
"age": "&2[&1].&",
"firstName": "&2[&1].&",
"lastname": "&2[&1].&",
"gender": "&2[&1].&",
"grade": "&2[&1].&",
"birthday": "&2[&1].&",
"address": {
"0": "&4[&3].&2[&1]",
"*": {
"*": {
"$": "&5[&4].&3[&2].@(0)" // key-value pairs are exchanged for this attribute
},
"value": "&4[&3].&2[&1].&"
}
}
}
}
}
},
{ // get rid of null components of the array
"operation": "modify-overwrite-beta",
"spec": {
"*": "=recursivelySquashNulls"
}
}
]
CodePudding user response:
[
{
"operation": "shift",
"spec": {
"userData": {
"*": {
"userId": "data.[&1].ID",
"*": "data.[&1].&",
"zipCode": {
"#custom-field1": "data[#3].address[#2].property",
"@": "data[#3].address[#2].value"
},
"street": {
"#custom-field2": "data[#3].address[#2].property",
"@": "data[#3].address[#2].value"
},
"city": {
"#custom-field3": "data[#3].address[#2].property",
"@": "data[#3].address[#2].value"
},
"country": {
"#custom-field4": "data[#3].address[#2].property",
"@": "data[#3].address[#2].value"
}
}
}
}
},
{ // get rid of null components of the array
"operation": "modify-overwrite-beta",
"spec": {
"*": "=recursivelySquashNulls"
}
}
]
CodePudding user response:
You may consider another library Josson to do the same job by shorter transformation statement.
https://github.com/octomix/josson
Deserialization
Josson josson = Josson.fromJsonString(
"{"
" \"userData\": ["
" {"
" \"userId\": \"1\","
" \"age\": \"20\","
" \"firstName\": \"firstname1\","
" \"lastname\": \"lastname1\","
" \"zipCode\": \"zipcode1\","
" \"street\": \"street1\","
" \"city\": \"city1\","
" \"country\": \"country\","
" \"gender\": \"gender1\","
" \"grade\": \"grade1\","
" \"birthday\": \"birthday1\""
" },"
" {"
" \"userId\": \"2\","
" \"age\": \"25\","
" \"firstName\": \"firstname2\","
" \"lastname\": \"lastname2\","
" \"zipCode\": \"zipcode2\","
" \"street\": \"street2\","
" \"city\": \"city2\","
" \"country\": \"country2\","
" \"gender\": \"gender2\","
" \"grade\": \"grade2\","
" \"birthday\": \"birthday2\""
" }"
" ]"
"}");
Transformation
JsonNode node = josson.getNode(
"map(data:userData"
" .field(ID:userId, userId:,"
" zipCode:, street:, city:, country:,"
" address:collect("
" map(property:'customer-field1',value:zipCode),"
" map(property:'customer-field2',value:street),"
" map(property:'customer-field3',value:city),"
" map(property:'customer-field4',value:country))))");
System.out.print(node.toPrettyString());
Output
{
"data" : [ {
"age" : "20",
"firstName" : "firstname1",
"lastname" : "lastname1",
"gender" : "gender1",
"grade" : "grade1",
"birthday" : "birthday1",
"ID" : "1",
"address" : [ {
"property" : "customer-field1",
"value" : "zipcode1"
}, {
"property" : "customer-field2",
"value" : "street1"
}, {
"property" : "customer-field3",
"value" : "city1"
}, {
"property" : "customer-field4",
"value" : "country"
} ]
}, {
"age" : "25",
"firstName" : "firstname2",
"lastname" : "lastname2",
"gender" : "gender2",
"grade" : "grade2",
"birthday" : "birthday2",
"ID" : "2",
"address" : [ {
"property" : "customer-field1",
"value" : "zipcode2"
}, {
"property" : "customer-field2",
"value" : "street2"
}, {
"property" : "customer-field3",
"value" : "city2"
}, {
"property" : "customer-field4",
"value" : "country2"
} ]
} ]
}