Flatten JSON array of objects that contain an array with Jolt - json

I'm using Jolt 0.1.0, and trying to transform the following JSON:
{
"records": [
{
"collectionId": "COLLECTION1",
"recordIds": [
"recA",
"recB"
]
},
{
"collectionId": "COLLECTION1",
"recordIds": [
"recC",
"recD",
"recE"
]
},
{
"collectionId": "COLLECTION2",
"recordIds": [
"recF",
"recG"
]
}
]
}
... to this:
{
"records": [
"COLLECTION1:recA",
"COLLECTION1:recB",
"COLLECTION1:recC",
"COLLECTION1:recD",
"COLLECTION1:recE",
"COLLECTION2:recF",
"COLLECTION2:recG"
]
}
I've made several attempts with the modify-default-beta operator and the concat function, but can't seem to make it work.

Very similar to https://github.com/bazaarvoice/jolt/issues/656 which required 4 steps.

Related

How to select JSON array (JSON substring) in JasperReport with JSONQL?

I want to create a report using Jaspersoft Studio with a json file as datasource. I want to select some fields from this json and also a substring of the original json. This should be done by jsonql.
First, an example with the "JSON language" in JasperSoftStudio:
gives the following result:
This is exactly what I want to have, the delivery note number as a field, and the barcodes as an array of objects / json substring.
What I am not able to do is, to achieve this with jsonql. The following query
gives the result
The following json was used for this example
{
"tour": {
"shipments": [
{
"containers": [
{
"boxes": [
{
"customerModule": "DEFG",
"deliveryDateTime": "2022-04-25 11:49:24.834000",
"boxNumber": 2
},
{
"customerModule": "ABCD",
"deliveryDateTime": "2022-04-25 11:50:24.810000",
"boxNumber": 1
}
],
"licensePlate": "123"
}
],
"deliveryNoteNumber": "6785000",
"barcodes": [
{
"content": "barcode_01_04"
},
{
"content": "barcode_03_04"
},
{
"content": "barcode_04_04"
}
]
},
{
"containers": [
{
"boxes": [
{
"customerModule": "ZXYV",
"deliveryDateTime": "2022-04-25 11:51:24.834000",
"boxNumber": 1
},
{
"customerModule": "UHGI",
"deliveryDateTime": "2022-04-25 11:52:24.834000",
"boxNumber": 2
}
],
"licensePlate": "987"
}
],
"deliveryNoteNumber": "6785001",
"barcodes": [
{
"content": "Barcode_01_04"
},
{
"content": "Barcode_02_04"
},
{
"content": "Barcode_04_04"
}
]
}
],
"handlingDateTime": "2022-04-25 11:50:24.883000"
}
I tried to use this documentation, but I could not get it working.
The JSONQL data source doesn't properly convert arrays to Strings for some reason.
What you can do is change the barcodes field from java.lang.String to java.lang.Object. You can do that by clicking Edit in the Fields tab and changing the Class Type for the field.
With java.lang.Object as field type, the field value will be the underlying JSON (Jackson) model array object. You can do $F{barcodes}.toString() if you need to explicitly convert it to a String in an expression.

Extract child key and flatten into parent object output in JQ

I'm trying to simplify a nested JSON structure using JQ
Input
[
{
"defaultBranchRef": {
"name": "main"
},
"nameWithOwner": "KyleMit/stack-posts"
},
{
"defaultBranchRef": {
"name": "master"
},
"nameWithOwner": "KyleMit/HelloSERN"
}
]
Desired Output
[
{
"nameWithOwner": "KyleMit/stack-posts",
"defaultBranchName": "main"
},
{
"nameWithOwner": "KyleMit/HelloSERN",
"defaultBranchName": "master"
}
]
Attempted Solution
I can retrieve each of the individual fields at any depth
Get nameWithOwner
[.[]|.nameWithOwner] // ["KyleMit/stack-posts","KyleMit/HelloSERN"]
Get defaultBranchRef.name
[.[]|.defaultBranchRef.name] // ["main","master"]
But can't quite get how to combine fields / selectors to return mulitple values
Just update |= the defaultBranchRef field to the content of its name subfield:
jq '.[].defaultBranchRef |= .name'
[
{
"defaultBranchRef": "main",
"nameWithOwner": "KyleMit/stack-posts"
},
{
"defaultBranchRef": "master",
"nameWithOwner": "KyleMit/HelloSERN"
}
]
Demo
Open to other solutions, but one way to combine is to use Object Construction like
[.[]|{nameWithOwner, defaultBranchName: .defaultBranchRef.name}]
Which results in the following output:
{
"nameWithOwner": "KyleMit/stack-posts",
"defaultBranchName": "main"
},
{
"nameWithOwner": "KyleMit/HelloSERN",
"defaultBranchName": "master"
}
]

JQ get data from an array of array

How can I get a value from an array of arrays. This is JSON from which I have to get the data:
{
"status": "success",
"data": {
"resultType": "matrix",
"result": [
{
"metric": {
"myMetric": "ABC"
},
"values": [
[
1633597734,
"64.54166666666667"
],
[
1633598034,
"65.51666666666667" <-- wanted value
]
]
}
]
}
}
I have to get value from the last array in values.
I tried the following:
jq .data.result.values input.json
jq .data.result.values[] input.json
jq .data.result.values[][] input.json
For every one the result is:
jq: error (at json:0): Cannot index array with string "values"
How can I get value from the last array in values?
You can use a negative index to enumerate from the back of an array: to get the last element of the last array in the values of the last element of result:
.data.result[-1].values[-1][-1]
demo: https://jqplay.org/s/YMpB8-A4-Q
filter:
.data.result[].values[1][1]?
input:
{
"status": "success",
"data": {
"resultType": "matrix",
"result": [
{
"metric": {
"myMetric": "ABC"
},
"values": [
[
1633597734,
"64.54166666666667"
],
[
1633598034,
"65.51666666666667"
]
]
}
]
}
}
output:
"65.51666666666667"

jmespath flatten multiple hash values

Ideally, I want to write a query that returns a flat list output: ["abc", "bcd", "cde", "def"] from the following JSON sample:
{
"l_l": [
[1,2,3],
[4,5,6]
],
"l_h_l": [
{ "n": [10,2,3] },
{ "n": [4,5,60] }
],
"l_h_m": [
{
"n": {
"1234": "abc",
"2345": "bcd"
}
}, {
"n": {
"3456": "cde",
"4567": "def"
}
}
]
}
The closest I can get is l_h_m[].n.* which returns the contents that I want as an unflattened list of lists:
[
[
"abc",
"bcd"
],
[
"cde",
"def"
]
]
jmespath lets you flatten lists of lists. Queries l_l[] and l_h_l[].n[] both returned flattened results, when the source json is structured that way.
Looks like your solution just required another flattening operator.
l_h_m[].n.*[]
returns
[
"abc",
"bcd",
"cde",
"def"
]

Create one JSON from another, with extra data va JQ

I have this file:
[
"smoke-tests",
"push-apps-manager"
]
I'd like to get this output using JQ:
{
"errands": [
{"name": "smoke-tests", "post_deploy": true},
{"name": "push-apps-manager", "post_deploy": true}
]
}
It seems so simple, yet, I have so much difficulty here...
It's a little tricky, since you need to embed the input into the list bound to the errands key. Start by creating the sequence of name/post_deploy objects:
% jq '.[] | {name: ., post_deploy: true}' names.json
{
"name": "smoke-tests",
"post_deploy": true
}
{
"name": "push-apps-manager",
"post_deploy": true
}
Then wrap that in the list in the outer object:
% jq '{errands: [.[] | {name: ., post_deploy: true}]}' names.json
{
"errands": [
{
"name": "smoke-tests",
"post_deploy": true
},
{
"name": "push-apps-manager",
"post_deploy": true
}
]
}
You can also use the map function (which I rarely remember how to use correctly, but it turns out is pretty simple here):
% jq '{errands: map({name:., post_deploy: true})}' names.json
Here is another approach. If you are new to jq it may be easiest to work towards the goal in small steps.
1) Start with the identity filter
.
which produces as expected
[
"smoke-tests",
"push-apps-manager"
]
2) next add the outer object with the "errands" key:
{ "errands": . }
which produces
{
"errands": [
"smoke-tests",
"push-apps-manager"
]
}
3) next move the data into an array
{ "errands": [ . ] }
which produces
{
"errands": [
[
"smoke-tests",
"push-apps-manager"
]
]
}
4) add the inner object with the "name" and "post_deploy" keys
{ "errands": [ { "name": ., "post_deploy": true } ] }
which produces
{
"errands": [
{
"name": [
"smoke-tests",
"push-apps-manager"
],
"post_deploy": true
}
]
}
5) Now we're really close. All we need to do is take advantage of jq's Object Construction behavior when an expression produces multiple results :
{ "errands": [ { "name": .[], "post_deploy": true } ] }
which gives us the desired result
{
"errands": [
{
"name": "smoke-tests",
"post_deploy": true
},
{
"name": "push-apps-manager",
"post_deploy": true
}
]
}