jmespath flatten multiple hash values - json

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

Related

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"

jOOQ JSON formatting as array of objects

I have the following (simplified) jOOQ query:
val result = context.select(
jsonObject(
key("id").value(ITEM.ID),
key("title").value(ITEM.NAAM),
key("resources").value(
jsonArrayAgg(ITEM_INHOUD.RESOURCE_ID).absentOnNull()
)
)
).from(ITEM).fetch()
Now the output that I want is:
[
{
"id": "0da04cc5-f70c-4fb3-b5c7-dc645d342631",
"title": "Title1",
"resources": [
"8b0f6d5c-67fc-47ca-be77-d1735e7721ce",
"ea0316db-1cfd-46d7-8260-5c1a4e65a0cd"
]
},
{
"id": "0f7e67e6-5187-47e2-9f1d-dab08feba38b",
"title": "Title2"
}
]
result.formtJSON() gives the following output:
{
"fields": [
{
"name": "json_object",
"type": "JSON"
}
],
"records": [
[
{
"id": "0da04cc5-f70c-4fb3-b5c7-dc645d342631",
"title": "Title 1"
}
]
]
}
Disabling the headers with result.formatJSON(JSONFormat.DEFAULT_FOR_RECORDS) will get me:
[
[
{
"id": "0da04cc5-f70c-4fb3-b5c7-dc645d342631",
"title": "Title1",
"resources": [
"8b0f6d5c-67fc-47ca-be77-d1735e7721ce",
"ea0316db-1cfd-46d7-8260-5c1a4e65a0cd"
]
}
],
[
{
"id": "0f7e67e6-5187-47e2-9f1d-dab08feba38b",
"title": "Title2"
}
]
]
where I don't want the extra array.
Further customizing the JSONformatter with result.formatJSON(JSONFormat().header(false).recordFormat(JSONFormat.RecordFormat.OBJECT)) I get:
[
{
"json_object": {
"id": "0da04cc5-f70c-4fb3-b5c7-dc645d342631",
"title": "Title1",
"resources": [
"8b0f6d5c-67fc-47ca-be77-d1735e7721ce",
"ea0316db-1cfd-46d7-8260-5c1a4e65a0cd"
]
}
},
{
"json_object": {
"id": "0f7e67e6-5187-47e2-9f1d-dab08feba38b",
"title": "Title2"
}
}
]
where I don't want the object wrapped in json_object.
Is there a way to get the output I want?
Doing it with Result.formatJSON()
This is clearly a flaw in the jOOQ 3.14.0 implementation of Result.formatJSON(). In the special case where there is only one column, and that column is of type JSON or JSONB, the column name may not really matter, and thus its contents should be flattened into the object describing the row. I've created a feature request for this: https://github.com/jOOQ/jOOQ/issues/10953. It will be available in jOOQ 3.15.0 and 3.14.4. You will be able to do this:
result.formatJSON(JSONFormat().header(false).wrapSingleColumnRecords(false));
The RecordFormat is irrelevant here. This works the same way for RecordFormat.ARRAY and RecordFormat.OBJECT
Doing it directly with SQL
Of course, you can always work around this by moving all the logic into SQL. You probably simplified your query by omitting a JOIN and GROUP BY. I'm assuming this is equivalent to what you want:
JSON result = context.select(
jsonArrayAgg(jsonObject(
key("id").value(ITEM.ID),
key("title").value(ITEM.NAAM),
key("resources").value(
select(jsonArrayAgg(ITEM_INHOUD.RESOURCE_ID).absentOnNull())
.from(ITEM_INHOUD)
.where(ITEM_INHOUD.ITEM_ID.eq(ITEM.ID))
)
))
).from(ITEM).fetchSingle().value1()
Note that JSON_ARRAYAGG() aggregates empty sets into NULL, not into an empty []. If that's a problem, use COALESCE()

Issue with cts.jsonPropertyScopeQuery and cts.jsonPropertyValueQuery with data types and field order

I have MarkLogic 9 on my database.
I have created the following documents in my database:
test1.json
{
"users": [
{
"userId": "A",
"value": 0
}
]
}
test2.json
{
"users": [
{
"userId": "A",
"value": "0"
}
]
}
test3.json
{
"users": [
{
"value": 0,
"userId": "A"
}
]
}
test4.json
{
"users": [
{
"value": "0",
"userId": "A"
}
]
}
I have run the following codes and have recorded the results:
cts.uris(“”, null, cts.jsonPropertyScopeQuery(
"users",
cts.andQuery(
[
cts.jsonPropertyValueQuery('userId', "A"),
cts.jsonPropertyValueQuery('value', "0"),
]
)
))
Result: test2.json, test4.json
cts.uris(“”, null, cts.jsonPropertyScopeQuery(
"users",
cts.andQuery(
[
cts.jsonPropertyValueQuery('userId', "A"),
cts.jsonPropertyValueQuery('value', 0),
]
)
))
Result: test3.json
I was wondering why test1.json did not return in the 2nd query while test3.json did. They both had the same values for fields but in different order. The order of the fields are different in test2.json and test4.json, however, the query returned both documents. The only difference between the 2 pairs that I can think of is that there are 2 data types for the field “value”, integer and string.
How would I go about resolving this issue?
https://docs.marklogic.com/cts.jsonPropertyValueQuery shows the value to match as an array.
If you want to keep the variants in data, maybe you can try something on the query side like cts.jsonPropertyValueQuery('value', ["0", 0])

Flatten JSON array of objects that contain an array with Jolt

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.

How to filter list by nested element using JSONPath?

How can one filter a list of items by a deeply nested value using JSONPath?
Test Data
[{
"identifiers": [
{
"extension": "foo"
}
]
},
{
"identifiers": [
{
"extension": "bar"
},
{
"extension": "baz"
}
]
}]
Expected Result
[{
"identifiers": [
{
"extension": "foo"
}
]
}]
I've tried the following, but none of them work. I used the JSONPath Tester to validate my results.
$[?(#.identifiers.[*].extension == 'foo')]
$[?(#.identifiers.*.extension == 'foo')]
$[?(#.identifiers[0].extension == 'foo')]
This
$..identifiers.[?(#.extension == "foo")]
works at http://jsonpath.herokuapp.com/ when you use Goessner.
at http://jsonpath.curiousconcept.com/ I keep getting errors.