JOLT filter array elements based on existence of a key field - arrays

Is it possible to filter array elements based on presence of a field.
My input JSON is as below:
{
"payload": {
"logical": {
"schemas": [
{
"name": "myschema",
"tables": [
{
"name": "myname",
"alias": "temp_alias",
"keys": [
{
"name": "value1",
"key": "key1",
"match": "match_val"
},
{
"name": "value1",
"key": "key2",
"match": "match_val"
},
{
"name": "value1",
"key": "key3"
},
{
"name": "value1",
"key": "key4"
}
]
}
]
}
]
}
}
}
Expected output is:
{
"payload": {
"logical": {
"schemas": [
{
"tables": [
{
"name": "myname",
"alias": "temp_alias",
"keys": {
"name": "value1",
"match": "match_val",
"key": [
"key1",
"key2"
]
}
}
]
}
]
}
}
}
If there is "match" field in "keys" element, then we will take "key" value from that element and put in the output array "key".
I am using this spec file, but not getting required output. Can anyone please suggest how to do it?
[
{
"operation": "shift",
"spec": {
"*": "&",
"payload": {
"*": "&",
"logical": {
"schemas": {
"*": {
"tables": {
"*": {
"name": "payload.logical.schemas[&3].tables[&1].name",
"alias": "payload.logical.schemas[&3].tables[&1].alias",
"keys": {
"*": {
"match": {
"match1|match2": {
"#2": {
"name": "payload.logical.schemas[&4].tables[&4].keys.name",
"match": "payload.logical.schemas[&4].tables[&4].keys.match",
"key": "payload.logical.schemas[&4].tables[&4].keys.key"
}
}
}
}
}
}
}
}
}
}
}
}
}
]

I got desired output with below spec file:
[
{
"operation": "shift",
"spec": {
"*": "&",
"payload": {
"*": "&",
"logical": {
"schemas": {
"*": {
"tables": {
"*": {
"name": "payload.logical.schemas[&3].tables[&1].name",
"alias": "payload.logical.schemas[&3].tables[&1].alias",
"keys": {
"*": {
"match": {
"*": {
"#(2,name)": "payload.logical.schemas[&7].tables[&5].keys[&3].name",
"#(2,match)": "payload.logical.schemas[&7].tables[&5].keys[&3].match",
"#(2,key)": "payload.logical.schemas[&7].tables[&5].keys[&3].key"
}
}
}
}
}
}
}
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": "&",
"payload": {
"*": "&",
"logical": {
"schemas": {
"*": {
"tables": {
"*": {
"name": "payload.logical.schemas[&3].tables[&1].name",
"alias": "payload.logical.schemas[&3].tables[&1].alias",
"keys": {
"*": {
"name": "payload.logical.schemas[&5].tables[&3].keys.name",
"match": "payload.logical.schemas[&5].tables[&3].keys.match",
"key": "payload.logical.schemas[&5].tables[&3].keys.key"
}
}
}
}
}
}
}
}
}
},
{
"operation": "cardinality",
"spec": {
"payload": {
"logical": {
"schemas": {
"*": {
"tables": {
"*": {
"keys": {
"name": "ONE",
"match": "ONE"
}
}
}
}
}
}
}
}
}
]

Related

JOLT : Make Nested Make a nested array as part of main array

I am trying to transform the JSON as below expected output. Stuck with the spec below. Can someone help in this?
There is an inner array with name "content" in the "results" array which I want to make it as a part of main array.
Input JSON
{
"total": 100,
"start": 1,
"page-length": 10,
"results": [
{
"index": 1,
"uri": "uri1/uri2",
"extracted": {
"kind": "object",
"content": [
{
"code": "A1",
"region": "APAC"
}
]
}
},
{
"index": 2,
"uri": "uri1/uri2",
"extracted": {
"kind": "object",
"content": [
{
"code": "B1",
"region": "AMER"
}
]
}
},
{
"index": 3,
"uri": "uri1/uri2",
"extracted": {
"kind": "object",
"content": [
{
"code": "C1",
"region": "APAC"
}
]
}
}
]
}
Expected json output
[
{
"code": "A1",
"region": "APAC"
},
{
"code": "B1",
"region": "AMER"
},
{
"code": "C1",
"region": "APAC"
}
]
Spec Tried
[
{
"operation": "shift",
"spec": {
"results": {
"*": {
"extracted": { "content": { "#": "&" } }
}
}
}
},
{
"operation": "shift",
"spec": {
"content": {
"#": "&"
}
}
}
]
Find the output below I am getting on Jolt tool
You can use # wildcard nested within square brackets in order to reach the level of the indexes of the "results" array such that
[
{
"operation": "shift",
"spec": {
"results": {
"*": {//the indexes of the "results" array
"extracted": {
"content": {
"*": {//the indexes of the "content" array
"*": "[#5].&"
}
}
}
}
}
}
}
]
Also the following spec, which repeats the content of the inner array without keys, will give the same result :
[
{
"operation": "shift",
"spec": {
"results": {
"*": {
"extracted": {
"content": {
"*": "[]"// [] seems like redundant but kept for the case the array has a single object.
}
}
}
}
}
}
]
which is quite similar to your tried one.

Jolt for input array to name value pair of array

Input is :
{
"Size": "2",
"done": "true",
"records": [
{
"Id": "a7g6s0000004GZuAAM",
"NN": "00096411.0",
"Name": "ISOLIN TRADE & INVEST"
},
{
"Id": "a7g6s0000004GZzAAM",
"Number": "00096412.0",
"Name": "ISOLIN"
}
]
}
Spec used:
[
{
"operation": "remove",
"spec": {
"records": {
"*": {
"attributes": " "
}
}
}
},
{
"operation": "shift",
"spec": {
"*": "&",
"records": {
"*": { //iterate on each object of records
"*": { //iterate on each element of object
"$": "Items[#1].Fields[].Name",
"#": "Items[#1].Fields[].Value"
}
}
}
}
}
]
Current Output:
{
"Size": "2",
"done": "true",
"Items": [
{
"Fields": [
{
"Name": "Id"
},
{
"Value": "a7g6s0000004GZuAAM"
},
{
"Name": "NN"
},
{
"Value": "00096411.0"
},
{
"Name": "Name"
},
{
"Value": "ISOLIN TRADE & INVEST"
},
{
"Name": "Id"
},
{
"Value": "a7g6s0000004GZzAAM"
},
{
"Name": "Number"
},
{
"Value": "00096412.0"
},
{
"Name": "Name"
},
{
"Value": "ISOLIN"
}
]
}
]
}
Expected output:
{
"Size": "2",
"done": "true",
"Items": [
{
"Fields": [
{
"Name": "Id",
"Value": "a7g6s0000004GZuAAM"
},
{
"Name": "NN",
"Value": "00096411.0"
},
{
"Name": "Name",
"Value": "ISOLIN TRADE & INVEST"
},
{
"Name": "Id",
"Value": "a7g6s0000004GZzAAM"
},
{
"Name": "Number",
"Value": "00096412.0"
},
{
"Name": "Name",
"Value": "ISOLIN"
}
]
}
]
}
You can seperate those attributes into individual objects through use of Items.&2.[#2]. pattern as prefix such as
[
{
"operation": "shift",
"spec": {
"*": "&",
"records": {
"*": {
"*": {
"$": "Items.&2.[#2].Name",
"#": "Items.&2.[#2].Value"
}
}
}
}
},
{
"operation": "shift",
"spec": {
"*": "&",
"Items": {
"*": {
"*": "Fields[]"
}
}
}
}
]

Unable to properly Transform nested array with JOLT

I'm trying to convert json nested array's element and unable to get expected result, either I properly get name element or schemaExtensions element but can't get both together.
Here is my input:
{
"rows": [
{
"content": {
"name": {
"content": "User"
},
"schemaExtensions": {
"content": [
{
"content": {
"schema": {
"content": "User"
},
"required": {
"content": true
}
}
}
]
}
}
}
]
}
And the JOlt spec definition:
[
{
"operation": "shift",
"spec": {
"rows": {
"*": {
"content": {
"name": {
"content": "[&3].name"
},
"schemaExtensions": {
"content": {
"*": {
"content": {
"schema": {
"content": "schemaExtensions.[&7].schema"
},
"required": {
"content": "schemaExtensions.[&7].required"
}
}
}
}
}
}
}
}
}
}
]
The expected result:
[ {
"name" : "User",
"schemaExtensions": [ {
"schema":"User",
"required":true
}]
}]
Here is the result I got when having both in my spec
[ {
"name" : "User"
} ]
And if I remove name from my spec, then I get my schemaExtensions properly:
{
"schemaExtensions" : [ {
"schema" : "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User",
"required" : true
} ]
}
You can start with three level nesting to roam before writing the branches(name&schemaExtensions) explicitly. No need to write other key names such as
[
{
"operation": "shift",
"spec": {
"*": {
"*": {
"*": {
"name": { "*": "&1" },
"schemaExtensions": {
"*": {
"*": { "*": { "*": { "*": "&5.&1" } } }
}
}
}
}
}
}
}
]
[
{
"operation": "shift",
"spec": {
"rows": {
"*": {
"content": {
"name": {
"content": "[].name"
},
"schemaExtensions": {
"content": {
"*": {
"content": {
"schema": {
"content": "[&7].schemaExtensions[&7].schema"
},
"required": {
"content": "[&7].schemaExtensions[&7].required"
}
}
}
}
}
}
}
}
}
}
]

Jolt transfer elements from child array to parent

Here i was trying merge elements from 2 child arrays in to its parent one and leave the other one and move the second array to two levels up.
Is there a way to change value on condition, like in the input below,
parties.party.sno ="1" , can this updated as parties..sno='Y'
input:
{
"Parties": [
{
"party": {
"partyId": "100005767",
"sno": 1,
"fn": "Th1mas",
"ln": "Edison",
"emails": [
{
"emailAddress": "jkjk#ui.com"
}
],
"addresses": [
{
"zip": ""
}
],
"shealth": [
{
"stcd": "TN",
"lno": "1"
}
]
},
"seq": {
"typeCd": "1"
}
}
]
}
Expected output:
{
"person": {
"first_name": "Th1mas",
"middle_initial": "Edison",
"last_name": "",
"email_address": "jkjk#ui.com",
"pinCode": ""
},
"shealth": {
"statecd": "ON"
},
//this is the seq no from party.sno
"primary": "Y",
"typeCd": "1"
}
tried spec like this:
[
{
"operation": "shift",
"spec": {
"Parties": {
"*": {
"party": {
"emails": {
"*": {
"emailAddress": "[&1].email_address",
"#(2,fn)": "[&1].first_name",
"#(2,ln)": "[&1].last_name"
}
},
"addresses": {
"*": {
"zip": "[&1].pinCode"
}
},
"shealth": {
"*": {
"stcd": "[&1].statecd"
}
}
}
}
}
}
}
]
This spec works,
"party": {
"sno": {
"1": {
"#Y": "primary"
}
},
Try applying the condition from the current level,
[
{
"operation": "shift",
"spec": {
"Parties": {
"*": {
"party": {
"sno": {
"1": {
"#Y": "primary"
}
},
"emails": {
"*": {
"emailAddress": "person.email_address",
"#(2,fn)": "person.first_name",
"#(2,ln)": "person.last_name"
}
},
"addresses": {
"*": {
"zip": "person.pinCode"
}
},
"shealth": {
"*": {
"stcd": "shealth.statecd"
}
}
},
"seq": {
"typeCd": "typeCd"
}
}
}
}
}
]

How to get object with certain property in arraylist in Jolt

I want to do a Jolt transformation with a json array, and i only want the ones with certain attribute.
For example:
Input:
{
"characteristic": [
{
"name": "BrandId",
"value": "b"
},
{
"name": "status",
"value": "SENT"
},
{
"name": "statusTxt",
"value": "sent"
}
]
}
I want output to be
{
"status":"SENT",
"statusTxt":"sent"
}
This will lead to the output you want based on your input:
[
{
"operation": "shift",
"spec": {
"characteristic": {
"*": {
"name": {
"status": {
"#(2,value)": "status"
},
"statusTxt": {
"#(2,value)": "statusTxt"
}
}
}
}
}
}
]

Resources