JOLT Transformation Boolean in a Sub-Segment of an Array - json

I have an SAP Idoc with additional customer specific fields as JSON
{
"E1EDL20": [
{
"VBELN": "1234567890",
"VSTEL": "ZO01",
"LGNUM": "123",
"NTGEW": "100.660",
"ANZPK": "00002",
"/XYZ/XYZ1234_E1EDL20": {
"ACTION": "POSTED",
"CONSIGNMENT": "12345678",
"FREIGHT_ORDER_EXTERNAL": "S123456789",
"IN_YARD": "X",
"IN_YARD_DATE": "20201123",
"IN_YARD_TIME": "100923"
},
"E1ADRM1": [
{
"PARTNER_Q": "LF",
"PARTNER_ID": "0000100000",
"/XYZ/XYZ1234_E1ADRM1": {
"SUPPLIER": "X"
}
},
{
"PARTNER_Q": "OSP",
"PARTNER_ID": "ZO01",
"/XYZ/XYZ1234_E1ADRM1": {
"SUPPLIER": "X"
}
}
]
}
]
}
Then I tried to remove the root array, rename the fields and do a type conversation of Strings to Integer, Double and Boolean and concatination of a date and time field to a timestamp. Here my Spec.
[
// Our E1EDL20 array has only one entry -> remove array
{
"operation": "cardinality",
"spec": {
"E1EDL20": "ONE"
}
},
// Move all contained fields to root level and properly rename them
{
"operation": "shift",
"spec": {
"E1EDL20": {
"VBELN": "deliveryInternal",
"VSTEL": "receivingPoint",
"LGNUM": "warehouseNumber",
"NTGEW": "netWeight",
"ANZPK": "numberOfPackages",
"/XYZ/XYZ1234_E1EDL20": {
"ACTION": "action",
"CONSIGNMENT": "consignment",
"FREIGHT_ORDER_EXTERNAL": "freightOrderExternal",
// Rename Content of the field to Boolean String
"IN_YARD": {
"X": { "#true": "inYard" },
"*": { "#false": "inYard" }
},
"IN_YARD_DATE": "inYardDateTmp",
"IN_YARD_TIME": "inYardTimeTmp"
},
// Suppliers
"E1ADRM1": {
"*": {
"PARTNER_Q": "supplier[&1].type",
"PARTNER_ID": "supplier[&1].number",
"/XYZ/XYZ1234_E1ADRM1": {
"SUPPLIER": {
"X": { "#true": "supplier[&2].supplier" },
"*": { "#false": "supplier[&2].supplier" }
}
}
}
}
}
}
},
{
"operation": "modify-overwrite-beta",
"spec": {
// Type conversions, String to Double or Integer
"netWeight": ["=toDouble", null],
"numberOfPackages": ["=toInteger", null],
// Type conversions, String to Boolean
"inYard": ["=toBoolean"],
"supplier": {
"*": {
"belomSupplier": ["=toBoolean"]
}
}
}
},
{
// Create Timestamp for inYardDate
"operation": "modify-default-beta",
"spec": {
"temp_DateYear": "=substring(#(1,inYardDateTmp),0,4)",
"temp_DateMonth": "=substring(#(1,inYardDateTmp),4,6)",
"temp_DateDay": "=substring(#(1,inYardDateTmp),6,8)",
"temp_TimeHours": "=substring(#(1,inYardTimeTmp),0,2)",
"temp_TimeMinutes": "=substring(#(1,inYardTimeTmp),2,4)",
"temp_TimeSeconds": "=substring(#(1,inYardTimeTmp),4,6)",
// Prior to this line, only temporary fields were created from substrings as preparation for the timestamp concatenateion
"inYardDate": "=concat(#(1,temp_DateYear),'-',#(1,temp_DateMonth),'-',#(1,temp_DateDay),'T',#(1,temp_TimeHours),':',#(1,temp_TimeMinutes),':',#(1,temp_prodTimeSeconds),'Z')"
}
},
{
// Remove temporary substring fields
"operation": "remove",
"spec": {
"temp_DateYear": "",
"temp_DateMonth": "",
"temp_DateDay": "",
"temp_TimeHours": "",
"temp_TimeMinutes": "",
"temp_TimeSeconds": "",
"inYardDateTmp": "",
"inYardTimeTmp": ""
}
}
]
I expected after the JOLT transforamtion an the following output.
{
"deliveryInternal" : "1234567890",
"receivingPoint" : "ZO01",
"warehouseNumber" : "123",
"netWeight" : 100.66,
"numberOfPackages" : 2,
"action" : "POSTED",
"consignment" : "12345678",
"freightOrderExternal" : "S123456789",
"inYard" : true,
"inYardDate" : "2020-11-23T10:09:Z",
"supplier" : [ {
"type" : "LF",
"number" : "0000100000",
"supplier" : true
}, {
"type" : "OSP",
"number" : "ZO01",
"supplier" : true
} ]
}
But i getting the following output.
{
"deliveryInternal" : "1234567890",
"receivingPoint" : "ZO01",
"warehouseNumber" : "123",
"netWeight" : 100.66,
"numberOfPackages" : 2,
"action" : "POSTED",
"consignment" : "12345678",
"freightOrderExternal" : "S123456789",
"inYard" : true,
"supplier" : [ {
"type" : "LF",
"number" : "0000100000"
}, {
"type" : "OSP",
"number" : "ZO01"
} ],
"inYardDate" : "2020-11-23T10:09:Z"
}
Does anyone have an idea how the problem can be solved ?

Are you just trying to add supplier: true to your suppliers? I couldn't see any other differences than that. If that's the case you can add this to the end of your chain spec:
{
// Add supplier = true to supplier elements
"operation": "shift",
"spec": {
"supplier": {
"*": {
"#true": "supplier[&1].supplier",
"*": "supplier[&1].&"
}
},
"*": "&"
}
}

Related

Jolt specification to transform json into name value pair

I am trying to convert below JSON into name value pair :
{
"Size": "2",
"done": "true",
"records": [
{
"Id": "a7g6s0000004GZuAAM",
"NN": "00096411.0",
"Name": "ISOLIN TRADE & INVEST",
"RecordType": {
"attributes": {
"type": "TestType"
},
"Name": "Term"
}
},
{
"Id": "a7g6s0000004GZzAAM",
"Number": "00096412.0",
"Name": "ISOLIN"
}
]
}
Expecting output JSON :
{
"Size" : "2",
"done" : "true",
"Items" : [ {
"Fields" : [ {
"Name" : "Id",
"Value" : "a7g6s0000004GZuAAM"
}, {
"Name" : "NN",
"Value" : "00096411.0"
}, {
"Name" : "Name",
"Value" : "ISOLIN TRADE & INVEST"
}, {
"Name" : "RecordType_Name",
"Value" : "Term"
} ]
}, {
"Fields" : [ {
"Name" : "Id",
"Value" : "a7g6s0000004GZzAAM"
}, {
"Name" : "Number",
"Value" : "00096412.0"
}, {
"Name" : "Name",
"Value" : "ISOLIN"
} ]
} ]
}
I am using below jolt spec but transformation of RecordType element is not as expected :
Jolt Spec :
[
{
"operation": "remove",
"spec": {
"records": {
"*": {
"attributes": " "
}
}
}
},
{
"operation": "shift",
"spec": {
"*": "&",
"records": {
"*": {
"*": {
"$": "Items.&2.[#2].Name",
"#": "Items.&2.[#2].Value"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": "&",
"Items": {
"*": {
"*": "Items.[#2].Fields[]"
}
}
}
}
]
How can I transform this into required format ?
I think remove transformation is not needed, and better to index each Field.
The trick for the solution would be distinguish RecordType attribute from the others by use of
"RecordType": {"Name": "Field&2.&1\\_&"}
such as
[
{
"operation": "shift",
"spec": {
"*": "&",
"records": {
"*": {
"*": "Field&1.&",
"RecordType": {
"Name": "Field&2.&1\\_&"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": "&",
"Field*": {
"*": {
"$": "Items[0].&2.[#2].Name",
"#": "Items[0].&2.[#2].Value"
}
}
}
}
]

How to convert array elements and strings into subsequent separate objects in array using JOLT?

I'm trying to transform a record using JOLT. String elements - from access_level field and Array elements (from tag field) have to be transformed to separate objects in properties array. But instead 2 elements are merged into one:
Here is the input:
{
"access_level": "public",
"tags": [
{
"id": 174,
"tag_name": "machine-learning",
"tag_path": "machine-learning"
},
{
"id": 393,
"tag_name": "chinese",
"tag_path": "chinese"
}
]
}
and spec file:
[
{
"operation": "shift",
"spec": {
"access_level": {
"*": {
"#1": "properties[#1].value",
"#terms-of-use": "properties[#1].type.code"
}
},
"tags": {
"*": {
"tag_name": "properties[#2].value",
"#keyword": "properties[#2].type.code"
}
}
}
}
]
expected output is:
{
"properties" : [
{
"value" : "public",
"type" : {
"code" : "terms-of-use"
}
},
{
"type" : {
"code" : "keyword"
},
"value" : "machine-learning"
},
{
"type" : {
"code" : "keyword"
},
"value" : "chinese"
} ]
}
but access_level and first value from tags are getting merged:
{
"properties" : [ {
"value" : [ "public", "machine-learning" ],
"type" : {
"code" : "keyword"
}
}, {
"type" : {
"code" : [ "terms-of-use", "keyword" ]
},
"value" : "chinese"
} ]
}
if there is no access_level on input the output looks fine - 2 objects are created in properties array
You can apply consecutive shift transformations using ampersand notations to determine the keys while producing one array(p), which's derived from tags, and an element, which's derived from access_level, in the first step; then rename that array to properties while adding that element to it in the last step in such a way :
[
{
"operation": "shift",
"spec": {
"tags": {
"*": {
"tag_name": "p.[&1].value",
"#keyword": "p.[&1].type.code"
}
},
"access_level": {
"*": {
"#(3,access_level)": "&1.value",
"#terms-of-use": "&1.type.code"
}
}
}
},
{
"operation": "shift",
"spec": {
"*": "properties"
}
}
]

JOLT Transformation - Extract field and put it to the top level

I have an SAP Idoc with additional customer specific fields as JSON
{
"E1EDL20": [
{
"VBELN": "1234567890",
"VSTEL": "ZO01",
"LGNUM": "123",
"NTGEW": "100.660",
"ANZPK": "00002",
"/XYZ/XYZ1234_E1EDL20": {
"ACTION": "POSTED",
"CONSIGNMENT": "12345678",
"FREIGHT_ORDER_EXTERNAL": "S123456789",
"IN_YARD": "X",
"IN_YARD_DATE": "20201123",
"IN_YARD_TIME": "100923"
},
"E1ADRM1": [
{
"PARTNER_Q": "LF",
"PARTNER_ID": "0000100000",
"/XYZ/XYZ1234_E1ADRM1": {
"SUPPLIER": "X"
}
},
{
"PARTNER_Q": "OSP",
"PARTNER_ID": "ZO01",
"/XYZ/XYZ1234_E1ADRM1": {
"SUPPLIER": "X"
}
}
]
}
]
}
I want to extract the first field of an array and put it to the top level.
This is the expected output:
{
"deliveryInternal" : "1234567890",
"receivingPoint" : "ZO01",
"warehouseNumber" : "123",
"netWeight" : "100.66",
"numberOfPackages" : "00002",
"type": "LF",
"action" : "POSTED",
"consignment" : "12345678",
"freightOrderExternal" : "S123456789",
"inYard" : "X",
"inYardDate" : "00002"
}
Does anyone have an idea how the problem can be solved ?
You can use shift operation with index-based keys as below
[
{
"operation": "shift",
"spec": {
"E1EDL20": {
"0": {
"VBELN": "deliveryInternal",
"VSTEL": "receivingPoint",
"/XYZ/XYZ1234_E1EDL20": {
"ACTION": "action"
},
"E1ADRM1": {
"0": {
"PARTNER_Q": "type"
}
}
}
}
}
}
]

jolt format with array of strings

Trying to make a Jolt script that will put in a single number line, then a array of strings in one single array and a tag on the end of that array. These are the values that I have been working with.
JSON INPUT
[
{
"foo": "111",
"bar": "222",
"sun": "333",
"ListofStrings": [
"Dog",
"Train"
],
"ID": "BLAH"
},
{
"foo": "999",
"bar": "222",
"sun": "777",
"ListofStrings": [
"CAT",
"PLANE"
],
"ID": "HAHA"
}
]
JOLT SPEC This is what I have been working with that prints out the ListofStrings but this is the one that works stably.
[
{
"operation": "shift",
"spec": {
"*": {
"foo": "input[].number",
"bar": "input[].number",
"sun": "input[].number",
"ListofStrings": "input[].List"
}
}
},
{
"operation": "default",
"spec": {
"app_id": "test",
"input": {
"*": {
"app_id": "test"
}
}
}
}
]
CURRENT OUTPUT
{
"input" : [ {
"number" : "111"
}, {
"number" : "222"
}, {
"number" : "333"
}, {
"List" : [ "Dog", "Train" ]
}, {
"number" : "999"
}, {
"number" : "222"
}, {
"number" : "777"
}, {
"List" : [ "Cat", "Car" ]
} ],
"app_id" : "test"
}
DESIRED OUTPUT
{
"input" : [ {
"number" : "111"
"List" : [ "Dog", "Train" ]
"ID": "BLAH_foo"
}, {
"number" : "222"
"List" : [ "Dog", "Train" ]
"ID": "BLAH_bar"
}, {
"number" : "333"
"List" : [ "Dog", "Train" ]
"ID": "BLAH_sun"
}, {
"number" : "999"
"List" : [ "Cat", "Car" ]
"ID": "HAHA_foo"
}, {
"number" : "222"
"List" : [ "Cat", "Car" ]
"ID": "HAHA_bar"
}, {
"number" : "777"
"List" : [ "Cat", "Car" ]
"ID": "HAHA_sun"
} ],
"app_id" : "test"
}
Check this spec
[
//Converting list to Map
{
"operation": "shift",
"spec": {
"*": {
"ListofStrings": null,
"*": {
"#": "#1.number",
"#(1,ListofStrings)": "#1.list"
}
}
}
},
//Shift the number and list to the input array
{
"operation": "shift",
"spec": {
"*": {
"$": "input[#2].number",
"#(0,list)": "input[#2].List"
}
}
}, {
"operation": "default",
"spec": {
"app_id": "test",
"input": {
"*": {
"app_id": "test"
}
}
}
}
]
Edit 1
Add the ID node to the map using first shift operation "ID": null, and "#(1,ID)": "#1.ID". Then shift the ID node to the input array in the second shift operation "#(0,ID)": "input[#2].ID".
[
//Converting list to Map
{
"operation": "shift",
"spec": {
"*": {
"ListofStrings": null,
"ID": null,
"*": {
"#": "#1.number",
"#(1,ListofStrings)": "#1.list",
"#(1,ID)": "#1.ID"
}
}
}
},
//Shift the number and list to the input array
{
"operation": "shift",
"spec": {
"*": {
"$": "input[#2].number",
"#(0,list)": "input[#2].List",
"#(0,ID)": "input[#2].ID"
}
}
}, {
"operation": "default",
"spec": {
"app_id": "test",
"input": {
"*": {
"app_id": "test"
}
}
}
}
]

Jolt, copy value along array

I want to transform a JSON using JOLT, in the following way.:
Input of json file
{
"Document_No": "ANG4",
"LineNo10": {
"Type": 1,
"Customer_No_": "1"
},
"LineNo11": {
"Type": 2,
"Customer_No_": "2"
},
"LineNo12": {
"Type": 3,
"Customer_No_": "3"
}
}
Desired output of json file
[
{
"Document_No":"ANG4"
"Type" : 1,
"Customer_No_" : "1",
"Line_No" : "10"
},
{
"Document_No":"ANG4"
"Type" : 2,
"Customer_No_" : "2",
"Line_No" : "11"
},
{
"Document_No":"ANG4"
"Type" : 3,
"Customer_No_" : "3",
"Line_No" : "12"
}
]
I don't lack a lot, but i don't know what transformations add to get the desired output
my Jolt specificaton is below
[
{
"operation": "shift",
"spec": {
"LineNo*": {
"#": "&",
"$": "&.Line_No"
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"#": "[]"
}
}
}
]
My output json file :
[ {
"Type" : 1,
"Customer_No_" : "1",
"Line_No" : "LineNo10"
}, {
"Type" : 2,
"Customer_No_" : "2",
"Line_No" : "LineNo11"
}, {
"Type" : 3,
"Customer_No_" : "3",
"Line_No" : "LineNo12"
} ]
Could anyone help me with this?
Spec
[
{
"operation": "shift",
"spec": {
"LineNo*": {
// copy Document_No down into the "LineNo" maps
"#(1,Document_No)": "&1.Document_No",
"$": "&1.Line_No",
"*": "&1.&"
}
}
},
{
// accumulate all the "built" LineNo's into an array
"operation": "shift",
"spec": {
"*": {
"#": "[]"
}
}
}
]