Arrange value in JOLT - json

I want "externalId" field before "status" field in JOLT.
Any idea why I am getting status before externalId? Also, how do I correct it?
I want Externalid first and then status in the output
/avoid this text please
Stack overflow is saying to many code
below
/
Input
{
"PURCHASE_ORDER_DISPATCH": {
"MsgData": {
"Transaction": {
"PO_POD_HDR_EVW1": {
"VENDOR_SETID": "WCOS",
"PO_ID": 25052,
"PO_POD_LN_EVW1": {
"WG_REQ_ID": 25694,
"PO_POD_SHP_EVW1": {
"FREIGHT_TERMS": "FOBDEST",
"BUSINESS_UNIT": "OFIC"
}
}
}
}
}
}
}
JOLT Spec-
[
{
"operation": "shift",
"spec": {
"#UPSERT": "integration-inbound:IntegrationDetails.integrationEntities.integrationEntity.integrationEntityHeader.action",
"*": {
"*": {
"*": {
"*": {
"PO_ID": "integration-inbound:IntegrationDetails.integrationEntities.integrationEntity.integrationEntityDetails.poDetails.externalId",
"#APPROVED": "integration-inbound:IntegrationDetails.integrationEntities.integrationEntity.integrationEntityDetails.poDetails.status",
"*": {
"WG_REQ_ID": "integration-inbound:IntegrationDetails.integrationEntities.integrationEntity.integrationEntityDetails.poDetails.poHeader.poDescription",
"*": {
"FREIGHT_TERMS": "integration-inbound:IntegrationDetails.integrationEntities.integrationEntity.integrationEntityDetails.poDetails.poHeader.deliveryTermCode"
}
}
}
}
}
}
}
}
]
Expected Output-
{
"integration-inbound:IntegrationDetails": {
"integrationEntities": {
"integrationEntity": {
"integrationEntityHeader": {
"action": "UPSERT"
},
"integrationEntityDetails": {
"poDetails": {
"externalId": 25052,
"status": "APPROVED",
"poHeader": {
"poDescription": 25694,
"deliveryTermCode": "FOBDEST"
}
}
}
}
}
}
}
New Input

This is the exact thing you want according to your desired output:
[
{
"operation": "shift",
"spec": {
"#UPSERT": "integration-inbound:IntegrationDetails.integrationEntities.integrationEntity.integrationEntityHeader.action",
"*": {
"*": {
"*": {
"*": {
"PO_ID": "integration-inbound:IntegrationDetails.integrationEntities.integrationEntity.integrationEntityDetails.poDetails.externalId",
"#APPROVED": "integration-inbound:IntegrationDetails.integrationEntities.integrationEntity.integrationEntityDetails.poDetails.status",
"*": {
"WG_REQ_ID": "integration-inbound:IntegrationDetails.integrationEntities.integrationEntity.integrationEntityDetails.poDetails.poHeader.poDescription",
"*": {
"FREIGHT_TERMS": "integration-inbound:IntegrationDetails.integrationEntities.integrationEntity.integrationEntityDetails.poDetails.poHeader.deliveryTermCode"
}
}
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": {
"*": {
"integrationEntityHeader": "&3.&2.&1.&",
"integrationEntityDetails": {
"*": {
"externalId": "&5.&4.&3.&2.&1.&",
"status": "&5.&4.&3.&2.&1.&",
"poHeader": "&5.&4.&3.&2.&1.&"
}
}
}
}
}
}
}
]
Note: If you want to sort based on what exactly you want you need to know that you shouldn't use * for selecting keys. instead of that, you should use the name of the key to getting it. like the top spec you can see I wrote externalId, status, and poHeader continuously.
But I did not understand why you need to sort externalId and status in your JSON output.
Update: If you have an array in your output, You can add the below spec to the end for preventing an array of the same values.
,
{
"operation": "cardinality",
"spec": {
"*": {
"*": {
"*": {
"*": {
"*": {
"status": "ONE"
}
}
}
}
}
}
}

Related

Masking cards usgins jolt

How can I iterate through list and replace some elements in it? I have this input
{
"clients": [
{
"clientId": "166734",
"info": {
"cards": [
"378282246310005",
"371449635398431"
]
}
}
]
}
I want mask cards like this "cards" : [ "3782*****0005", "3714*****8431" ]
You can use shift transformations to convert the cards array to indexed and 0,1,** labeled objects in order to prepare for modify transformation spec in which substring and concat functions are used such as
[
{
"operation": "shift",
"spec": {
"clients": {
"*": {
"*": "&2[#2].&",
"info": {
"cards": {
"*": {
"#": "&5[#5].&3.&2.&1.&"
}
}
}
}
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"clients": {
"*": {
"info": {
"cards": {
"*": {
"p1": "=substring(#(1,&1),0,4)",
"p2": "=substring(#(1,&1),11,15)",
"cs": "=concat(#(1,p1),'********',#(1,p2))"
}
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"clients": {
"*": {
"*": "&2[#2].&",
"info": {
"cards": {
"*": {
"cs": "&5[#5].&3.&2[]"
}
}
}
}
}
}
}
]

Jolt Spec for masking cards

How can I iterate through list and replace some elements in it?
I have this input
{
"clients": [
{
"clientId": "166734",
"info": {
"cards": [
"378282246310005",
"371449635398431"
]
}
}
]
}
What I expect cards will looks like this "cards" : [ "3782", "3714" ]
But in my spec do not work substring
[
{
"operation": "modify-overwrite-beta",
"spec": {
"clients": {
"*": {
"info": {
"cards": {
"*": "=substring(#(1,&),0,#(1,4))"
}
}
}
}
}
}
]
Note 1:
You should not use #(1,&) for getting an array index.
#(1,&) says: Go up 1 level (cards) and get 0 and 1 key from the array with &. But You have an array and should get the index from it.
You can say get & in an array like this: #(1,[&])
Note 2:
For getting the first 4 elements in the string you don't need the #(1,4). just say 4
Simpler solution:
We can get the current level without going up 1 level with #(0) or #0: #0,0,4
[
{
"operation": "modify-overwrite-beta",
"spec": {
"clients": {
"*": {
"info": {
"cards": {
"*": "=substring(#0,0,4)"
}
}
}
}
}
}
]
You can use shift transformations to tame the cards array in order to prepare for modify transformation spec such as
[
{
"operation": "shift",
"spec": {
"clients": {
"*": {
"*": "&2[#2].&",
"info": {
"cards": {
"*": {
"#": "&5[#5].&3.&2.&"
}
}
}
}
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
"clients": {
"*": {
"info": {
"cards": {
"*": "=substring(#(1,&),0,4)"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"clients": {
"*": {
"*": "&2[#2].&",
"info": {
"cards": {
"*": "&4[#4].&2.&1[#1]"
}
}
}
}
}
}
]
If there can always only exist two components for cards then we make the whole spec shorter by using [first/last]Element functions, otherwise use "=(#(1,cards[0/1]))" by individually writing such as
[
{
"operation": "modify-overwrite-beta",
"spec": {
"clients": {
"*": {
"info": {
"c0": "=firstElement(#(1,cards))", //or "=(#(1,cards[0]))"
"c1": "=lastElement(#(1,cards))", //or "=(#(1,cards[1]))"
"cards0": "=substring(#(1,c0),0,4)",
"cards1": "=substring(#(1,c1),0,4)"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"clients": {
"*": {
"*": "&2[#2].&",
"info": {
"*s*": "&3[#3].&1.&(0,1)s"
}
}
}
}
}
]

How to write JOLT Spec for nested arrays

I am trying to transform a JSON using JOLT. This JSON consists of nested arrays and I am not able to transform it correctly. Can someone please help. Thanks.
{
"root": [
{
"id": "1234",
"password": "key1234",
"devices": [
{
"details": {
"deviceType": "tv-iot",
"deviceId": "tv-iot-111"
}
},
{
"details": {
"deviceType": "machine-iot",
"deviceId": "machine-iot-999"
}
}
]
},
{
"id": "6789",
"password": "key6789",
"devices": [
{
"details": {
"deviceType": "phone-iot",
"deviceId": "phone-iot-111"
}
},
{
"details": {
"deviceType": "mobile-iot",
"deviceId": "mobile-iot-999"
}
}
]
}
]
}
This is the spec that I have written.
[
{
"operation": "shift",
"spec": {
"root": {
"*": {
"id": "[&1].userid",
"password": "[&1].pwd",
"devices": {
"*": {
"details": {
"deviceType": "[&2].deviceCategory",
"deviceId": "[&2].deviceUniqueValue"
}
}
}
}
}
}
}
]
The expected JSON that I am looking for is:
[
{
"userid": "1234",
"pwd": "key1234",
"devices": [
{
"details": {
"deviceCategory": "tv-iot",
"deviceUniqueValue": "tv-iot-111"
}
},
{
"details": {
"deviceCategory": "machine-iot",
"deviceUniqueValue": "machine-iot-999"
}
}
]
},
{
"userid": "6789",
"pwd": "key6789",
"devices": [
{
"details": {
"deviceCategory": "phone-iot",
"deviceUniqueValue": "phone-iot-111"
}
},
{
"details": {
"deviceCategory": "mobile-iot",
"deviceUniqueValue": "mobile-iot-999"
}
}
]
}
]
However, I get this wrong output. Somehow, my nested objects are getting transformed into list.
[
{
"userid" : "1234",
"pwd" : "key1234",
"deviceCategory" : [ "tv-iot", "phone-iot" ],
"deviceUniqueValue" : [ "tv-iot-111", "phone-iot-111" ]
},
{
"deviceCategory" : [ "machine-iot", "mobile-iot" ],
"deviceUniqueValue" : [ "machine-iot-999", "mobile-iot-999" ],
"userid" : "6789",
"pwd" : "key6789"
}
]
I am unable to figure out what is wrong. Can someone please help?
UPDATE(Solution): Was able to come up with a shorter spec that works as well !
[
{
"operation": "shift",
"spec": {
"root": {
"*": {
"id": "[&1].userId",
"password": "[&1].pwd",
"*": "[&1].&"
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"devices": {
"*": {
"details": {
"deviceType": "[&4].&3.[&2].&1.deviceCategory",
"deviceId": "[&4].&3.[&2].&1.deviceUniqueVal"
}
}
},
"*": "[&1].&"
}
}
}
]
You can start by deep diving into the innermost object while partitioning the sub-objects by id values through a shift transformation such as
[
{
"operation": "shift",
"spec": {
"root": {
"*": {
"devices": {
"*": {
"details": {
"*": {
"#(4,id)": "#(5,id).userid",
"#(4,password)": "#(5,id).pwd",
"#": "#(5,id).devicedetails[&3].&2.&1"
}
}
}
}
}
}
}
},
{
// get rid of top level object names
"operation": "shift",
"spec": {
"*": ""
}
},
{
// get rid of repeating components of each arrays respectively
"operation": "cardinality",
"spec": {
"*": {
"us*": "ONE",
"pwd": "ONE"
}
}
},
{
// determine new key names for attributes respectively
"operation": "modify-overwrite-beta",
"spec": {
"*": {
"*": {
"*": {
"*": {
"deviceCategory": "=(#(1,deviceType))",
"deviceUniqueValue": "=(#(1,deviceId))"
}
}
}
}
}
},
{
// get rid of extra elements generated
"operation": "remove",
"spec": {
"*": {
"*": {
"*": {
"*": {
"deviceType": "",
"deviceId": ""
}
}
}
}
}
}
]

With JOLT need to Transform JSON object with If Then Else Condition

Below is my Input Json
[
{
"correlationId": "12345",
"payloadFormat": "Money",
"payload": {
"DE35": "123654ABC54678",
"DE45": "898454PQR54678"
}
}
]
I need to Trnsaform this json in such a way if DE35 has value say of substring 6-9 then take DE35 value in Transform Json, if DE35 do not have value then Take DE45 value in transform Json.
So output will be if DE35 Available then
[ {
"COR_ID" : "12345",
"payloadFormat" : "Money",
"EXT_SERV_CD":"ABC"
} ]
if DE35 is not available then the output should be
[ {
"COR_ID" : "12345",
"payloadFormat" : "Money",
"EXT_SERV_CD":"PQR"
} ]
I am using Below JOLT spec to do Transformation but it is not working.
[
{
"operation": "shift",
"spec": {
"*": {
"#": "&",
"payload": {
"DE|DE35": "&2.payload.TMPDE35"
}
}
}
}, {
"operation": "modify-default-beta",
"spec": {
"*": {
"payload": {
"DE35Val": "=substring(#(1,TMPDE35), 6, 9)"
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"#": "&",
"payload": {
"DE|DE45": "&2.payload.TMPDE45"
}
}
}
}, {
"operation": "modify-default-beta",
"spec": {
"*": {
"payload": {
"DE45Val": "=substring(#(1,TMPDE45), 6, 9)"
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"correlationId": "[&1].COR_ID",
"payloadFormat": "[&1].payloadFormat",
"payload": {
"DE35Val": {
"ABC": {
"DE35Val": "[#3].payload.EXT_SERV_CD"
},
"false": {
"DE45Val": "[#3].payload.EXT_SERV_CD"
}
}
}
}
}
}
]
Please suggest where I am making mistake.
This spec should work for you
[
{
"operation": "modify-default-beta",
"spec": {
"*": {
"TmpDE35": "=substring(#(1,payload.DE35), 6, 9)",
"TmpDE45": "=substring(#(1,payload.DE45), 6, 9)"
}
}
},
{
"operation": "modify-default-beta",
"spec": {
"*": {
"Tmp35_45": "=concat(#(1,TmpDE35), #(1,TmpDE45))"
}
}
},
{
"operation": "modify-default-beta",
"spec": {
"*": {
"EXT_SERV_CD": "=substring(#(1,Tmp35_45), 0, 3)"
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": "[&1].&",
"Tmp*": null,
"payload": null
}
}
}
]
The solution idea:
Move the substrings of the DE35, DE45 fields to the TmpDE35, TmpDE45
Concatenate TmpDE35, TMPDE45 and store it in the Tmp35_45. If TmpE35 is empty then the first 3 characters will come from TmpDE45
Get the substring Tmp35_45
Clean up, shift

sort an array of json document

I'm wondering if it's possible to sort or bring the min value in case of an array of json. I read something about this issue but found nothing.
This is the Input:
{
"intData": [
{
"DATE": "2018",
"NOME": "raf"
},
{
"DATE": "2001",
"NOME": "fabio"
},
{
"DATE": "2002",
"NOME": "fabiola"
}
]
}
I would:
{
"intData": [
{
"DATE": "2001",
"NOME": "fabio"
},
{
"DATE": "2002",
"NOME": "fabiola"
},
{
"DATE": "2018",
"NOME": "raf"
}
]
}
or
{
"DATE": "2001",
"NOME": "fabio"
}
Is it possible?
Ordered Results
The steps are as follows:
Create object with structure: $.DATE.NOME.#
Sort it
Turn it back into an array
[
{
"operation": "shift",
"spec": {
"intData": {
"*": {
"#": "#(1,DATE).#(1,NOME)"
}
}
}
},
{
"operation": "sort"
},
{
"operation": "shift",
"spec": {
"*": {
"*": {
"#": "intData.[]"
}
}
}
}
]
First result
The steps are as follows:
Create object with structure: $.DATE.NOME.#
Sort it
Turn it back into an array
Get first result
[
{
"operation": "shift",
"spec": {
"intData": {
"*": {
"#": "#(1,DATE).#(1,NOME)"
}
}
}
},
{
"operation": "sort"
},
{
"operation": "shift",
"spec": {
"*": {
"*": {
"#": "[]"
}
}
}
},
{
"operation": "shift",
"spec": {
"0": {
"#": ""
}
}
}
]