Jolt transform array of objects to key-value - json

Problems
Hi, I'm using Jolt to transform e-commerce products data. For e.g:
[
{
"objectID": 1,
"string_facet": [
{
"facet_name": "eco_collection",
"facet_value": "No"
},
{
"facet_name": "performance_fabric",
"facet_value": "No"
}
]
},
{
"objectID": 2,
"string_facet": [
{
"facet_name": "activity",
"facet_value": [
"Hiking"
]
}
]
}
]
And my desired output is:
[
{
"objectID": 1,
"string_facet": {
"eco_collection": "No",
"performance_fabric": "No"
}
},
{
"objectID": 2,
"string_facet": {
"activity": [
"Hiking"
]
}
}
]
What I have done so far
I have tried this spec, but it isn't what I need:
[
{
"operation": "shift",
"spec": {
"*": {
"*": "[&1].&",
"string_facet": {
"*": {
"#facet_value": "[&1].string_facet.#facet_name"
}
}
}
}
}
]
I'm looking for an explanation in addition to solution.
Any help would be much appreciated!

You principally need "#facet_value": "#facet_name" match, start with it, then add
&2 to represent going two levels up and grabbing the key name's value(string_facet)
&3 to represent going three levels up and grabbing the indices of the main array to accumulate each attributes nested within individual object of their own.
Then, add an extra shift transformation spec to get rid of the integer key names such as
[
{
"operation": "shift",
"spec": {
"*": {
"*": "&1.&",
"string_facet": {
"*": {
"#facet_value": "&3.&2.#facet_name"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": ""
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

Related

Pull elements out of two arrays to make a "flat" item list

I need to merge array data from two different arrays from the Input JSON and make a flat list of items in the Output JSON. The first array contains the key required for the output and the second array contains the value.
So far, all my attempts at a spec haven't even come close, which is why I haven't listed one. Please see the Input and Desired Output below. Thanks for any help!!
Input JSON :
{
"data": [
{
"2": {
"value": "DC1"
},
"3": {
"value": 5
}
},
{
"2": {
"value": "DC2"
},
"3": {
"value": 10
}
}
],
"fields": [
{
"id": 2,
"label": "DataCenter",
"type": "text"
},
{
"id": 3,
"label": "CCount",
"type": "numeric"
}
],
"metadata": {
"numFields": 2,
"numRecords": 2,
"skip": 0,
"totalRecords": 2
}
}
Desired Output JSON:
[
{
"DataCenter": "DC1",
"CCount": "5"
},
{
"DataCenter": "DC2",
"CCount": "10"
}
]
You can use this spec:
[
{
"operation": "shift",
"spec": {
"data": "&",
"fields": {
"*": {
"label": "fields.#(1,id)"
}
}
}
},
{
"operation": "shift",
"spec": {
"data": {
"*": {
"*": {
"*": "[&2].#(4,fields.&1)"
}
}
}
}
}
]
In your desired output CCount value is a string, You can add the below spec to change an integer to a string.
,
{
"operation": "modify-overwrite-beta",
"spec": {
"*": {
"CCount": "=toString"
}
}
}
You might reciprocally match id value of fields array vs. the object keys of the data array within a common object within the first shift transformation spec in order to prepare for the second one in which we tile the attributes into their individual objects such as
[
{
"operation": "shift",
"spec": {
"*": { // represents the node for both "data" and "fields" arrays
"*": {
"*": {
"value": "&1.&",
"#1,label": "#2,id.&"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"value": {
"*": "[&].#2,label"
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

JOLT Specification for converting filed value to field name

I am trying to convert the below JSON payload into a JSON that has the field name as the value of the field:
The jolt file that I have is working if field values are different. But if field values are the same then it is giving an array in the response.
Can you please help to provide jolt specifications for this?
Input JSON Payload:
{
"action": {
"Success": true,
"records": [
{
"Id": "Test_abc",
"SubscriptionID": "ID_1"
},
{
"Id": "Test_abc",
"SubscriptionID": "ID_2"
},
{
"Id": "Test_xyz",
"SubscriptionID": "ID_3"
}
],
"type": "update"
}
}
Expected output:
{
"action": {
"Success": true,
"records": {
"Test_abc": {
"SubscriptionID": "ID_1"
},
"Test_abc": {
"SubscriptionID": "ID_2"
},
"Test_xyz": {
"SubscriptionID": "ID_3"
}
},
"type": "update"
}
}
Solution not found yet.
You can use the following shift transformation spec
[
{
"operation": "shift",
"spec": {
"*": {
"*": "&1.&", // &1 replicates the literal "action"
"records": {
"*": {
"S*": "&3.&2.#(1,Id).&" // &3 replicates the literal "action" (by going three level up the tree), &2 for "records", & replicates the current level attribute
}
}
}
}
}
]
presumingly converting one of the Id value from Test_abc to another one such as Test_def, since the desired output is wrong as a JSON value(There cannot be more than one object with the same tag at the same level)
Your output is wrong. You can't have multiple objects with the same keys.
If You want to support all objects of records array, You should bring them into an array like this spec:
[
{
"operation": "shift",
"spec": {
"*": {
"*": "&1.&",
"records": {
"*": {
"S*ID": "&3.&2[].#(1,Id).&"
}
}
}
}
}
]
But, if you want to have an object as your records in the output, You should remove the duplicate ID like this spec:
[
{
"operation": "shift",
"spec": {
"*": {
"*": "&1.&",
"records": {
"*": {
"S*ID": "&3.&2.#(1,Id).&"
}
}
}
}
},
{
"operation": "cardinality",
"spec": {
"*": {
"records": {
"*": {
"*": "ONE"
}
}
}
}
}
]

JOLT JSON transform values from one-to-many to one-to-one

I'm trying to map one key to each value in array to a new array by using JOLT.
Could someone please help give me a solution for this:
My JSON:
[
{
"person_id": "1",
"resources": ["asd", "zxc"]
},
{
"person_id": "2",
"resources": ["ghj", "asd"]
}
]
And my expected JSON:
[
{
"person_id": "1",
"resource": "asd"
},
{
"person_id": "1",
"resource": "zxc"
},
{
"person_id": "2",
"resource": "ghj"
},
{
"person_id": "2",
"resource": "asd"
}
]
I had tried this Jolt Specification
[
{
"operation": "shift",
"spec": {
"*": {
"resources": {
"*": {
"#(2,person_id)": "[&].person_id",
"#": "[&].resource"
}
}
}
}
}
]
But no luck it always maps all values at the same index to 1 array.
You can use two consecutive shift transformation specs by walking through the resources array within the first one such that
[
{
"operation": "shift",
"spec": {
"*": {
"*s": { // this tecnique stands for extracting by the replacement of the asterisk through use of &(2,1) below
"*": {
"#(2,person_id)": "[&3].&1.person_id", // to separate by indexes of the array to generate three level for three independent objects
"#": "[&3].&1.&(2,1)"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": ""
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is
You can use this jolt spec:
[
{
"operation": "shift",
"spec": {
"*": {
"*s": {
"*": {
"#(2,person_id)": "#(1).person_id",
"#": "#(1).&(2,1)"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": ""
}
}
]

Jolt Transform filter values using another value of the json

I have this JSON:
{
"mapTrue": "true",
"code": [
"X",
"Y",
"Z"
],
"expired": [
"true",
"false",
"true"
]
}
I want to use the "mapTrue" value in order to filter the "code" array.
If "mapTrue": "true", I'll take the 0 and 2 values in "expired" array, therefore I need to output
"code": ["X", "Z"].
Using the same logic, for "mapTrue: "false" I'll return "code": ["Y"].
This specification returns the right "code" array but it doesn't use the "mapTrue" value.
[
{
"operation": "shift",
"spec": {
"expired": {
"*": {
"true": {
"#(3,code[&1])": "code"
}
}
}
}
}
]
That's where my problem is.
This works:
[
{
"operation": "shift",
"spec": {
"expired": "#(1,mapTrue)",
"code": "code"
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": {
"&1": {
"#(3,code[&1])": "code[]"
}
}
}
}
}
]
An alternative option would be using the following specs
[
{
// separate the values for "true", "false" while match "code" with the value of "mapTrue"
"operation": "shift",
"spec": {
"c*": {
"*": "#(2,expired[&])", // walk through the indexes(0,1,2) of "expired" array while matching with the components of "code"
"#(1,mapTrue)": "&1"
}
}
},
{
"operation": "shift",
"spec": {
"c*": {
"*": {
"#(2,&)": "&2" // grab the value going tree up two levels by using "#(2,&)", and copy the main object's label "code" by grabbing it after going tree two levels again
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

JOLT Specification to Transform field value to field name

I am trying to convert below json payload into a json payload which has field name as the value of the field:
Can you please help to provide jold specification for this ?
Input JSON Payload :
{
"action": {
"allowPartialSuccess": false,
"records": [
{
"recordid": "a4c6364e-4446-47d0-b014-c20ca014fdb3",
"ShipToCustomerTextualAddress__c": "TestAddress1",
"ResellerPO__c": "TestAddress1",
"InvoiceCDBID__c": "TestAddress1"
},
{
"recordid": "73781a94-9660-4f69-9bde-f2bf1991317d",
"ShipToCustomerTextualAddress__c": "TestAddress2",
"ResellerPO__c": "TestAddress2",
"InvoiceCDBID__c": "TestAddress2"
}
],
"type": "update"
}
}
Desired Output Payload :
{
"action": {
"allowPartialSuccess": false,
"records": {
"a4c6364e-4446-47d0-b014-c20ca014fdb3": {
"ShipToCustomerTextualAddress__c": "TestAddress1",
"ResellerPO__c": "TestAddress1",
"InvoiceCDBID__c": "TestAddress1"
},
"73781a94-9660-4f69-9bde-f2bf1991317d": {
"ShipToCustomerTextualAddress__c": "TestAddress2",
"ResellerPO__c": "TestAddress2",
"InvoiceCDBID__c": "TestAddress2"
}
},
"type": "update"
}
}
This will help you resolve it.
#(level,attribute) -->does the work.
[
{
"operation": "shift",
"spec": {
"action": {
"*": "action.&",
"records": {
"*": {
"ShipToCustomerTextualAddress__c": "action.records.#(1,recordid).&",
"ResellerPO__c": "action.records.#(1,recordid).&",
"InvoiceCDBID__c": "action.records.#(1,recordid).&"
}
}
}
}
}
]
You can think symbolically through use of ampersands to replicate the respective values within a shift transformation, and a remove transformation in order to get rid of the undesired attribute(recordid) at the end such as
[
{
"operation": "shift",
"spec": {
"*": {
"records": {
"*": "&2.&1.#(0,recordid)" // &2(going two levels up) stands for replicating "action", &1 is for "records"
},
"*": "&1.&" // which represents the "else" case(eg. all but the "records" object); &1 is for "action", and & is for "records"
}
}
},
{
"operation": "remove",
"spec": {
"*": {
"*": {
"*": {
"recordid": ""
}
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is
You would use this for solution this problem.
[
{
"operation": "shift",
"spec": {
"action": {
"*": "action.&",
"records": {
"*": "action.records.#recordid"
}
}
}
}
]