Json array elements duplication using jolt - json

I want to know if jolt can handle the following transformation:
{
"interface": [
{
"field": "A",
"ip": [
"1.1.1.1",
"1.1.1.2"
]
},
{
"field": "B",
"ip": [
"1.1.1.3"
]
}
]
}
to
{
"interface": [
{
"field": "A",
"ip": "1.1.1.1"
},
{
"field": "A",
"ip": "1.1.1.2"
},
{
"field": "B",
"ip": "1.1.1.3"
}
]
}
i.e for a JSON array containing a child array, create one version of parent item for each of its child array item.
Can jolt do that?

This can be achieved by doing a two stage shift:
Create an array of arrays
Then flatten the array of arrays
[
{
"operation": "shift",
"spec": {
"interface": {
"*": {
"ip": {
"*": {
"#": "[&3].[&1].ip",
"#(2,field)": "[&3].[&1].field"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"*": "interface.[]"
}
}
}
]

It is not complete answer, but maybe that helps you somehow or someone else could help?
[
{
"operation": "shift",
"spec": {
"interface": {
"*": {
"ip": {
"*": {
"#": "ip",
"#(2,field)": "field"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"ip": {
"*": {
"#": "interface[&1].ip",
"#(2,field)": {
"???": "interface[&2].field" // How to take proper index of an array?
}
}
}
}
}
]

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 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 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"
}
}
}
}
]

JOLT shift through properties with different names

I have a JSON:
{
"relations": {
"advertiser_id": {
"9968": {
"name": "Advance/Unicredit",
"id": 9968
},
"10103": {
"name": "Advance/ ORIMI",
"id": 10103
}
},
"campaign_id": {
"256292": {
"name": "Interests_Aidata",
"id": 256292,
"advertiser_id": 9968
},
"257717": {
"name": "G_14.04",
"id": 257717,
"advertiser_id": 10103
}
}
}
}
I thought that it's an easy shift operation, but I'm stuck because of all values inside random property names like "9968": I don't understand how to move through json with these different propertie names.
Expected Output:
[
{
"name": "Interests_Aidata",
"id": 256292,
"advertiser_id": 9968
},
{
"name": "G_14.04",
"id": 257717,
"advertiser_id": 10103
}
]
UPDATE
Is it possible to add top-level (under relations) advertiser_id or campaign_id as additional propety like in an example?
[
{
"name": "Interests_Aidata",
"id": 256292,
"advertiser_id": 9968,
"entity_type": "campaign_id"
},
{
"name": "G_14.04",
"id": 257717,
"advertiser_id": 10103,
"entity_type": "campaign_id"
}
]
If your aim is to accumulate each array of objects under those properties(advertiser_id and campaign_id), then use the following spec
[
{
"operation": "shift",
"spec": {
"*": {
"*": {
"*": {
"#": "&2"
}
}
}
}
}
]
If you're interested in only the stuff under campaign_id as lately edited, then use
[
{
"operation": "shift",
"spec": {
"*": {
"campaign_id": {
"*": {
"#": ""
}
}
}
}
}
]
The following spec can be used the desired result determined by the last update
[
{
"operation": "shift",
"spec": {
"*": {
"campaign_id": {
"*": {
"*": "[#2].&",
"$1": "[#2].entity_type"
}
}
}
}
}
]

Jolt spec to transform an array of elements into objects with ids

Jolt is new to me and I have been struggling with this issue till the point where I created this post.
I want to turn this:
{
"Properties": [{
"Id": "property1",
"Values": ["randomValue1", "randomValue2"]
}, {
"Id": "property2",
"Values": "randomValue3"
}, {
"Id": "property3",
"Values": "randomValue4"
}]
}
into this
{
"Properties": [{
"Id": "property1",
"Values": "randomValue1"
},{
"Id": "property1",
"Values": "randomValue2"
}, {
"Id": "property2",
"Values": "randomValue3"
}, {
"Id": "property3",
"Values": "randomValue4"
}]
}
The values for each property can be 1 value or an array of an unknown amount of values.
I changed the following json into what is seen in the first json already:
{
"Properties": {
"property1": ["randomValue1", "randomValue1"],
"property2": ["randomValue3"],
"property3": ["randomValue4"]
}
}
Spec:
[{
"operation": "shift",
"spec": {
"Properties": {
"*": {
"*": "Properties[#2].Values",
"$": "Properties[#2].Id"
}
}
}
}]
Property names on RHS are generic and the number of values for a property can differ as well.
Thank you in advanced for taking the time to assist me.
check if this helps:
[
{
"operation": "cardinality",
"spec": {
"Properties": {
"*": {
// normalize values to always be a list
"Values": "MANY"
}
}
}
},
{
"operation": "shift",
"spec": {
"Properties": {
"*": {
"Values": {
"*": {
// create arrays with values and ids
"#": "Values",
"#(2,Id)": "Id"
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"Values": {
"*": {
// create the final list joining ids and values at the indexes you want
"#": "Properties[&1].Values",
"#(2,Id[#1])": "Properties[&1].Id"
}
}
}
}
]