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
Related
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"
}
}
}
}
]
I am having the below document structure:
[
{
"network_type": "ex",
"rack": [
{
"xxxx": {
"asn": 111111,
"nodes": {
"business": [
"sk550abcc1eb01.abc.com",
"sk550abcc1eb10.abc.com",
"sk550abcc1eb19.abc.com",
"sk550abcc1eb28.abc.com"
]
},
"region": "ex-01",
"zone": "01a"
}
}
]
}
]
I need to rename/update the key array element "xxxx" to "details".
I tried the below command, but it doesn't seem to work.
db.collection.update({},
{
$rename: {
"rack.xxxx": "details"
}
})
Link: https://mongoplayground.net/p/9dcDP-VKZ55
Please help me.
You can't direct $rename the field name which is within the array.
Instead,
Iterate with document(s) in the rank array, create the details field with the value of xxxx and next append this field to each document.
Remove the path with $rank.xxxx to remove the xxxx field from the document(s) in the rank array.
db.collection.update({},
[
{
$set: {
rack: {
$map: {
input: "$rack",
in: {
$mergeObjects: [
{
"details": "$$this.xxxx"
},
"$$this"
]
}
}
}
}
},
{
$unset: "rack.xxxx"
}
])
Sample Mongo Playground
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)"
}
}
}
}
]
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"
}
}
}
]
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