Jolt Convert string attribut to array only if it match to a condition - arrays

I have this input
[
{
"attributeKey": "foo",
"stringValue": "fooValue",
},
{
"attributeKey": "bar",
"stringValue": "barValue1¤barValue2",
}
]
And I want to transform it to this output
{
"foo" : "fooValue",
"bar" : ["barValue1", "barValue2"]
}
The rules are :
Whenever we found an element in the input array that have an attribute stringValue containing ¤ character we should split/transform it to an array of strings.
The type of the value result in the output is very important : for attributeKey that have a stringValue containing ¤ separator the result should be an array of strings (splitted values), otherwise the result should be a string.
PLEASE NOT THAT THE VALUES OF THE attributeKey ARE NOT KNOWN BEFOREHAND, THEY MAY CHANGE ANYTIME!
I have tried with this spec :
[
{
"operation": "shift",
"spec": {
"*": {
"#(1,[&].stringValue)": {
"*": {
"$": "#(3,attributeKey)"
},
"*\\¤*": {
"$": "#(3,attributeKey)"
}
}
}
}
}
]
But it gives me only this :
{
"foo" : "fooValue",
"bar" : "barValue1¤barValue2"
}
I tied many attempts to split the result but without succeeding !
UPDATE
#barbaros solution, adding :
{
"operation": "modify-overwrite-beta",
"spec": {
"bar": "=split('¤', #(1,&))"
}
}
gives the desired result only if we know the values of attributeKey before hands, for example in my case I could receive a json containing different values :
[
{
"attributeKey": "baz",
"stringValue": "bazValue1¤bazValue2",
},
]
In this case the provided solution will not work, since values of attributeKey changes every time ! So we should be able to perform the split/transformation no matter the value of attributeKey in the input.

You can add the following modify-overwrite-beta spec containing split function to the current shift spec
{
"operation": "modify-overwrite-beta",
"spec": {
"bar": "=split('¤', #(1,&))"
}
}
Edit :
Depending on your need, you can make modify-overwrite-beta spec. the first step, and walk through the objects of the array, and then shorten the shift spec as below
[
{
"operation": "modify-overwrite-beta",
"spec": {
"*": {
"stringValue": "=split('¤', #(1,&))"
}
}
},
{
"operation": "shift",
"spec": {
"*": {
"#(2,[&].stringValue)": {
"*": "#(2,attributeKey)"
}
}
}
}
]

Related

Looping through multiple line items in a single array output in JOLT

I want to write a Jolt definition that loops through each object in my attachment array, and move the object to the data array. At the same time, it should map single object attachment nest, and move the object to the data object.
Currently my spec below is working when my attachment block is an array.
Input :
{
"IntegrationEntities": {
"integrationEntity": [
{
"integrationEntityHeader": {
"attachments": {
"attachment": [
{
"name": "EV10044.docx"
},
{
"name": "Test1.txt"
}
]
}
}
}
]
}
}
JOLT Spec :
[
{
"operation": "shift",
"spec": {
"IntegrationEntities": {
"integrationEntity": {
"*": {
"integrationEntityHeader": {
"attachments": {
"attachment": {
"*": {
"name": "data[&1].filename"
}
}
}
}
}
}
}
}
}
]
Current Output :
{
"data": [
{
"filename": "EV10044.docx"
},
{
"filename": "Test1.txt"
}
]
}
I want to handle the scenario in a way where regardless if the attachment is an array or object it should give the input. Currently it fails if the attachment block is an object and gives the output as NULL.
IF Input is:
{
"IntegrationEntities": {
"integrationEntity": [
{
"integrationEntityHeader": {
"attachments": {
"attachment": {
"name": "EV10044.docx"
}
}
}
}
]
}
}
Desired Output:
{
"data": {
"filename": "EV10044.docx"
}
}
You can use this spec:
[
{
"operation": "shift",
"spec": {
"IntegrationEntities": {
"integrationEntity": {
"*": {
"integrationEntityHeader": {
"attachments": {
"attachment": {
"name": "data.filename",
"*": {
"name": "data[&1].filename"
}
}
}
}
}
}
}
}
}
]
I just added the below line to your spec. So if you have name in the attachment it is assumed that you have 1 attachment. If no name is found it is assumed you have an array and your other codes is correct.
"name": "data.filename",
An option is to use a shift transformation spec in which the objects are qualified by path expressions and the arrays are constructed along with sub-indexes by symbolic expression "*": { such as
[
{
"operation": "shift",
"spec": {
"#IntegrationEntities.integrationEntity": {
"*": { // indexes of the array
"#integrationEntityHeader.attachments.attachment": {
"*": { // indexes of the array
"*": "data[].file&", // if "attachment" is an array
"#1,name": "data.file&" // if "attachment" is an object
}
}
}
}
}
}
]
Btw, if you didn't need to rename the innermost attribute name to fieldname, the following shorter spec would suffice :
[
{
"operation": "shift",
"spec": {
"#IntegrationEntities.integrationEntity": {
"*": {
"#integrationEntityHeader.attachments.attachment": "data"
}
}
}
}
]

Transform Object in Array with Jolt

I'm trying to convert a JSON object to an array contained one element
Input :
{
"record": {
"file_header": {
"file_name": "TEST_FILE"
},
"scheda_contatto": {
"phone_number": "5555-111-222-333",
"type_call": 1
}
}
}
i want scheda_contatto to be an array with only 1 element
Output:
{
"record": {
"file_header": {
"file_name": "TEST_FILE"
},
"scheda_contatto": [
{
"phone_number": "5555-111-222-333",
"type_call": 1
}
]
}
}
You can use &1[0].& in order to nest all innermost sub-elements(&) of the single object by square-brackets([0]) with key name scheda_contatto(&1 under s*) while prefixing each value identifier by &1 and &2 respectively in order to replicate the wrapper key name record for both such as
[
{
"operation": "shift",
"spec": {
"rec*": {
"*": "&1.&",
"s*": {
"*": "&2.&1[0].&"
}
}
}
}
]
the demo on the site http://jolt-demo.appspot.com/ is

Is is possible to concatenate values from two different objects in Jolt

I would like to know if it is possible in Jolt to concatenate values from different objects. I've successfully concatenated "orderType" (value=ABC) and "minorCode" (value 0003) from the "orderInformation" object to create an output key of "Job.JobTypeCd" (value ABC0003). I would like to add the "serviceType" value as a prefix to that new key so the output value would be "123ABC0003".
Example input
{
"orderInformation": {
"orderType": "ABC",
"minorCode": "0003"
},
"account": {
"serviceType": "123"
}
}
Current Spec
[
{
"operation": "modify-default-beta",
"spec": {
"orderInformation": {
"JobType": "=concat(#(1,orderType),#(1,minorCode))"
}
}
},
{
"operation": "shift",
"spec": {
"orderInformation": {
"JobType": "Job.JobTypeCd"
},
"account": {
"serviceType": "Job.AddThisAsPrefix2JobTypeCd"
}
}
}
]
Current output
{
"Job" : {
"JobTypeCd" : "ABC0003",
"AddThisAsPrefix2JobTypeCd" : "123"
}
}
Desired output
{
"Job" : {
"JobTypeCd" : "123ABC0003"
}
}
You can include the serviceType value to the same concat operation as below.
"JobType": "=concat(#(2,account.serviceType),#(1,orderType),#(1,minorCode))"
Full spec
[
{
"operation": "modify-default-beta",
"spec": {
"orderInformation": {
"JobType": "=concat(#(2,account.serviceType),#(1,orderType),#(1,minorCode))"
}
}
},
{
"operation": "shift",
"spec": {
"orderInformation": {
"JobType": "Job.JobTypeCd"
}
}
}
]

jolt shift array up a level, but preserve the array even if empty

I struggled hard with how to title this one. This is from the twitter sample stream. I need the hashtag text pulled out into an array at the top level. I have that working, but if there is just one hashtag it jolt's to a single string, and if there are no hashtags (twitter gives back an empty array in that case), then the field disappears. I want to do the same thing with the URL field & user mentions.
Input JSON:
{"entities": {
"hashtags": [{"text": "somethingClever",
"indices": [22, 28]},
{"text": "somethingLessClever",
"indices": [30, 40]}],
"urls": [],
"user_mentions": [{
"screen_name": "username",
"indices": [3, 19]
}],
"symbols": []
}
Desired output:
{
"hashtags": ["somethingClever"],
"urls": [],
"user_mentions": ["username"]
}
But what I'm getting is this:
Actual output, note screen_name is not an array and urls is altogether missing. That is the crux of my problem.
{
"hashtag_text" : [ "somethingClever", "somethingLessClever" ],
"screen_name" : "username"
}
Here is my jolt spec so far:
[
{
"operation": "shift",
"spec": {
"entities": {
"hashtags": { "*": { "text": ".hashtag_text" } },
"urls": { "*": { "url_text": ".urls" } },
"user_mentions": { "*": { "screen_name": ".&" } }
}
}
}
]
I figured it out. I used shift to bring the necessary array elements to the next level up (from entities to root). Next I used the default operation to make it still be an array even if the array was empty. Lastly, I used the cardinality operation to make it be an array even if there is only one element.
Hopefully this helps somebody.
[
{
"operation": "shift",
"spec": {
"entities": {
"hashtags": { "*": { "text": ".hashtags" } },
"urls": { "*": { "url_text": ".urls" } },
"user_mentions": { "*": { "screen_name": ".&" } }
}
}
},
{
"operation": "default",
"spec": {
"hashtags[]": {},
"urls[]": {},
"screen_name[]": {}
}
},
{
"operation": "cardinality",
"spec": {
"hashtags": "MANY",
"urls": "MANY",
"screen_name": "MANY"
}
}
]

How to use jolt to parse array of array

I want to use jolt to parse the json. But I can't get the age value in the first level successfully. May someone help me?
The input json is like this:
{
"name": "abc",
"age": "20",
"Photos": [
{
"a": "AAA.jpg",
"b": "BBB.jpg",
"XXX123": [
{
"v1": "AAA.jpg",
"v2": "BBB.jpg"
}
]
}
]
}
My Spec:
[
{
"operation": "shift",
"spec": {
"Photos": {
"*": {
"XXX123": {
"*": {
//"*": "&2.[&1].&",
"#(2,a)": "&2.[&1].a",
"#(2,b)": "&2.[&1].b",
"#(3,age)": "&3.[&1].age"
}
}
}
}
}
}
]
The output I want:
{
"XXX123" : [ {
"a" : "AAA.jpg",
"b" : "BBB.jpg",
"age" : "20"
} ]
}
Spec
[
{
"operation": "shift",
"spec": {
"Photos": {
"*": {
"XXX123": {
"*": {
//"*": "&2.[&1].&",
"#(2,a)": "&2.[&1].a",
"#(2,b)": "&2.[&1].b",
"#(4,age)": "&2.[&1].age"
}
}
}
}
}
}
]
You were close.
"#(3,age)": "&3.[&1].age"
needed
"#(4,age)": "&2.[&1].age"
From where that line was you needed to go up the tree 5 levels.
Counting from Zero
0 -> "*"
1 -> "XXX123"
2 -> "*"
3 -> "Photos"
4 -> your top level input
then lookup "age" in the top level map

Resources