How to remove a particular field containing certain value using Jolt - json

I have the below JSON structure :
{
"data": {
"a1": "value1",
"a2": "value1",
"a3": "value1",
"collection": [
{
"events": [
{
"x1": 123,
"x2": "NA",
"x3": 5678
},
{
"x1": 432,
"x2": 854,
"x3": 912
}
]
}
]
}
}
I would like to remove the field x2 whenever it has value as "NA" or "NV" using Jolt
Desired output :
{
"data": {
"a1": "value1",
"a2": "value1",
"a3": "value1",
"collection": [
{
"events": [
{
"x1": 123,
"x3": 5678
},
{
"x1": 432,
"x2": 854,
"x3": 912
}
]
}
]
}
}

You can use the following shift transformation spec with conditional logic
[
{
"operation": "shift",
"spec": {
"data": {
"*": "&1.&",
"collection": {
"*": {
"events": {
"*": {
"x2": {
"NA|NV": { // | is OR operator
"*": ""
},
"*": {
"#1": "&7.&6[&5].&4[&3].&2" // &7 represents the level of "data", &6 represents the level of "collection", [&5] -> the indexes of it, &4 -> the level of "events" etc.
}
},
"*": "&5.&4[&3].&2[&1].&" // reduce two level with respect to the above value identifier
}
}
}
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

Related

JOLT JSON Transformation - Filter Array by Dynamic Attribute Value Not Working

The filtering of JSON array works fine if we specify a static search value. This does not work if we apply a dynamic value.
Tried by dynamically passing the value.
Added below the input json along with the jolt spec for your reference.
Input:
{
"selected_key": "key2",
"keys": [
{
"name": "value1",
"key": "key1"
},
{
"name": "value21",
"key": "key2"
},
{
"name": "value22",
"key": "key2"
},
{
"name": "value3",
"key": "key3"
},
{
"name": "value4",
"key": "key4"
}
]
}
JOLT Spec:
[
{
"operation": "shift",
"spec": {
"keys": {
"*": {
"key": {
"#(4,selected_key)": {
"#2": "test"
}
}
}
}
}
}
]
Expected Output:
{
"test": [
{
"name": "value21",
"key": "key2"
},
{
"name": "value22",
"key": "key2"
}
]
}
Output:
The spec is not filtering any value and all the array items are added to the output json
{
"test": [
{
"name": "value1",
"key": "key1"
},
{
"name": "value21",
"key": "key2"
},
{
"name": "value22",
"key": "key2"
},
{
"name": "value3",
"key": "key3"
},
{
"name": "value4",
"key": "key4"
}
]
}
You can use two consecutive shift transformation spec such as
[
{// tag the objects or array of objects by common "key" values
"operation": "shift",
"spec": {
"*": "&",
"keys": {
"*": {
"#": "#(1,key)"
}
}
}
},
{// rename "key2" with "test"
"operation": "shift",
"spec": {
"selected_key": {
"*": {
"#(2,&)": "test"
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

A JOLT transformation question about mapping reference

This is an input that needs to be transformed using Jolt Transformation to obtain the expected output.
I am attempting to create a jolt transformation for the below input:
{
"flights": [
{
"id": "123",
"route": "BJS-SIN"
},
{
"id": "456",
"route": "SIN-PEK"
},
{
"id": "789",
"route": "SIN-BJS"
}
],
"prices": [
{
"id": "abc",
"amount": 560
},
{
"id": "def",
"amount": 780
}
],
"solutions": [
{
"price-ref": "abc",
"flights-ref": [
"123",
"456"
]
},
{
"price-ref": "def",
"flights-ref": [
"123",
"789"
]
}
]
}
Desired output would like :
{
"solutions": [
{
"flights": [
{
"id": "123",
"route": "BJS-SIN"
},
{
"id": "456",
"route": "SIN-PEK"
}
],
"price": {
"id": "abc",
"amount": 560
}
},
{
"flights": [
{
"id": "123",
"route": "BJS-SIN"
},
{
"id": "789",
"route": "SIN-BJS"
}
],
"price": {
"id": "def",
"amount": 780
}
}
]
}
As the output, all the data should be constructed refer to the solutions node. How about the mapping expression in JOLT?
all the values from the source json are generated randomly and the keys names are fixed.
I had tried many times but could not find the right spec, so please help.
You can use this spec:
[
{
"operation": "shift",
"spec": {
"*": "&",
"flights|prices": {
"*": {
"*": "&2.#(1,id).&"
}
}
}
},
{
"operation": "shift",
"spec": {
"solutions": {
"*": {
"flights*": {
"*": {
"*": {
"#(6,flights.&)": "&5[&4].flights[&2]"
}
}
},
"price*": {
"*": {
"#(5,prices.&)": "&4[&3].price"
}
}
}
}
}
}
]

Using JOLT convert List to Array of Objects

I've spent quite a lot of time figuring it out but I'm stuck, I have a nested JSON and I want to enrich the values of "attr" with those matching the keys of "codes", thanks in advance.
My Input JSON:
{
"items": {
"a1b2xxxx": {
"name": "item 1",
"attr": [
"A",
"B",
"C"
]
},
"c2b2cxxxx": {
"name": "item 2",
"attr": [
"D",
"E",
"F"
]
}
},
"codes": {
"A": {
"color": "green"
},
"B": {
"size": "M"
},
"C": {
"sku": "NS"
},
"D": {
"stock": 2
},
"E": {
"some_key": "some_value"
},
"F": {
"foo": "bar"
}
}
}
My Desired Output JSON:
{
"items": {
"a1b2xxxx": {
"name": "item 1",
"attr": {
"A": {
"color": "green"
},
"B": {
"size": "M"
},
"C": {
"sku": "NS"
}
}
},
"c2b2xxxx": {
"name": "item 2",
"attr": {
"D": {
"stock": 2
},
"E": {
"some_key": "some_value"
},
"F": {
"foo": "bar"
}
}
}
},
"codes": {
"A": {
"color": "green"
},
"B": {
"size": "M"
},
"C": {
"sku": "NS"
},
"D": {
"stock": 2
},
"E": {
"some_key": "some_value"
},
"F": {
"foo": "bar"
}
}
}
My approach is following:
Using cardinality operation convert attr to an array of objects
Then maybe I can map values from codes using modify-default-beta
But I am stuck at step 1. Here is my transformer:
[
{
"operation": "cardinality",
"spec": {
"items": {
"*": {
"attr": "ONE"
}
}
}
}
]
You can use a single shift transformation such as
[
{
"operation": "shift",
"spec": {
"items": {
"*": {
"name": "&2.&1.&",
"attr": {
"*": { // the level of the indexes of "attr" array, eg. 0,1,2
"*": { // the level of the components of "attr" array, eg. A,B,C,D,E,F
"#(5,codes.&)": "&5.&4.&" // going four levels up the tree to get the object labels of "a1b2xxxx" and "c2b2cxxxx"
}
}
}
}
},
"*": "&" // objects(attributes or array) other than "items", eg. "codes"
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is
Another spec can be like this:
You can use values of array with # and use them as key #(0) like "#": "&4.&3.&2.#(0).color"
[
{
"operation": "shift",
"spec": {
"*": "&",
"items": {
"*": {
"*": "&2.&1.&",
"attr": {
"*": {
"#": "&4.&3.&2.#(0).color"
}
}
}
}
}
}
]

Jolt unnest list to top level

I have a JSON:
[
{
"id": 1015380,
"type": "campaign",
"stats": [
{
"message_sends_by_any_user": 13,
"ctr": "0.094",
}
]
},
{
"id": 1015695,
"type": "campaign",
"stats": [
{
"message_sends_by_any_user": 7,
"ctr": "0.091",
}
]
}
]
I want to "unnested" stats list to top level. JOLT config:
[
{
"operation": "shift",
"spec": {
"*": {
"id": "[&1].id",
"type": "[&1].type",
"stats": {
"*": "[&2].&"
}
}
}
}
]
Expected:
[
{
"id": 1015380,
"type": "campaign",
"message_sends_by_any_user": 13,
"ctr": "0.094",
},
{
"id": 1015695,
"type": "campaign",
"message_sends_by_any_user": 7,
"ctr": "0.091"
}
]
But actual output contains array indexes like this:
[
{
"id" : 1015380,
"type" : "campaign",
"0" : {
"message_sends_by_any_user" : 13,
"ctr" : "0.094"
}, ...
How to avoid these indexes?
You can prefer walking through the indexes of the stats list by taking id and type attributes inside such as
[
{
"operation": "shift",
"spec": {
"*": {
"stats": {
"*": {
"#(2,id)": "[&3].id",
"#(2,type)": "[&3].type",
"*": "[&3].&"
}
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com is

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