In Postgres 13, for the below query, the jsonb values are getting filtered correctly based on "priority":
SELECT jsonb_path_query(
'{
"100": {
"name": "test",
"priority": 5
},
"101": {
"name": "test2",
"priority": 10
},
"102": {
"name": "test3",
"priority": 15
}
}'
, '$.* ? (#.priority > 10)')
Output:
{
"name": "test3",
"priority": 15
}
But I want to get the root key also. In this case I want to get the root for "test3" which is "102". To achieve this, I tried the below query:
SELECT jsonb_path_query(
'{
"100": {
"name": "test",
"priority": 5
},
"101": {
"name": "test2",
"priority": 10
},
"102": {
"name": "test3",
"priority": 15
}
}'
, '$ ? (#.*.priority > 10)')
But the output data is not getting filtered based on "priority".
Here is the output:
{
"100": {
"name": "test",
"priority": 5
},
"101": {
"name": "test2",
"priority": 10
},
"102": {
"name": "test3",
"priority": 15
}
}
The desired output would be:
{
"102": {
"name": "test3",
"priority": 15
}
}
How can I filter the data using an SQL/JSON path expression and the get the root key as well?
The task would be simple with a JSON array instead of a JSON object (which would seem like the more appropriate structure for your sample data):
SELECT jsonb_path_query(
'[
{
"100": {
"name": "test",
"priority": 5
}
},
{
"101": {
"name": "test2",
"priority": 10
}
},
{
"102": {
"name": "test3",
"priority": 15
}
}
]'
, '$[*] ? (#.*.priority > 10)');
While working with a JSON object, one way would be with the .keyvalue() method:
SELECT jsonb_path_query(
'{
"100": {
"name": "test",
"priority": 5
},
"101": {
"name": "test2",
"priority": 10
},
"102": {
"name": "test3",
"priority": 15
}
}'
, '$.keyvalue() ? (#.value.priority > 10)');
Returns:
{"id": 0, "key": "102", "value": {"name": "test3", "priority": 15}}
The manual:
object . keyvalue() → array
The object's key-value pairs, represented as an array of objects
containing three fields: "key", "value", and "id"; "id" is a
unique identifier of the object the key-value pair belongs to
To get your desired JSON value exactly:
SELECT jsonb_build_object(j->>'key', j->'value')
FROM (
SELECT jsonb_path_query(
'{
"100": {
"name": "test",
"priority": 5
},
"101": {
"name": "test2",
"priority": 10
},
"102": {
"name": "test3",
"priority": 15
}
}'
, '$.keyvalue() ? (#.value.priority > 10)')
) sub(j);
Returns:
{"102": {"name": "test3", "priority": 15}}
db<>fiddle here
Related
I tried to filter below json payload characters[] array which is having result as 'valid' and data[] array name as 'WBB' and priority as '1'
I tried below code but not working can some one help me ?.
flatten(payload.offers.category.characters) filter ((item, index) -> item.result=='valid' and flatten(item.data) filter ((item, index) -> item.name=='WBB' and item.priority==1))
Json payload
{
"offers": [
{
"id": 100,
"name": "Test1",
"category": {
"characters": [
{
"result": "valid",
"data": [
{
"name": "WBB",
"priority": 1
},
{
"name": "ILL",
"priority": 2
}
]
}
]
}
},
{
"id": 200,
"name": "Test2",
"category": {
"characters": [
{
"data": [
{
"name": "ISS",
"priority": 1
},
{
"name": "ILL",
"priority": 2
}
]
}
]
}
},
{
"id": 300,
"name": "Test3",
"category": {
"characters": [
{
"data": [
{
"name": "WSS",
"priority": 1
},
{
"name": "ILL",
"priority": 2
}
]
}
]
}
}
]
}
Expected payload
[
{
"name": "WBB",
"priority": 1
}
]
flatten((flatten(payload.offers..characters) filter $.result == "valid").data) filter ($.name=="WBB" and $.priority == 1)
flatten(payload..data) filter ((item, index) -> item.name == 'WBB' )
Let's say I have a complex struct, perhaps with ten levels of nesting and repeated fields. Is there a built-in way to compare these two objects to see if they are the same minus the sorting of keys? This may be related to: Compare two json values for equality. An example might be:
{
"id": "0001",
"type": "donut",
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "type": "Powdered Sugar" , "id": "5007"},
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
],
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
}
}
Versus:
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "type": "None", "id": "5001" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
From the previous question, we learnt that JSON type allows such a comparison, then it is just a matter of how to use JSON type as a proxy to compare the 2 structs
with data as (
select struct<a string, b struct<x string, y string>>('a', ('x', 'y')) col1,
struct<b struct<y string, x string>, a string>(('y', 'x'), 'a') col2,
) select col1,
col2,
TO_JSON_STRING(PARSE_JSON(TO_JSON_STRING(col1))) = TO_JSON_STRING(PARSE_JSON(TO_JSON_STRING(col2)))
from data;
I am trying to get data from my database but when I show and make it become api response, I have some problem for grouping it based on productid.
I have response data that created based on golang like this:
[
{
"product_id": "1",
"product_name": "Cardigan",
"pitems": [
{
"id": "625ad1bc-66c5-440e-a527-d029d401ec2b",
"name": "Box",
"qty": 1
},
{
"id": "625ad1bc-66c6-440e-a527-d029d401ec2b",
"name": "test items1",
"qty": 1
},
{
"id": "625ad1bc-66c7-440e-a527-d029d401ec2b",
"name": "test items2",
"qty": 1
},
{
"id": "625ad1bc-66c8-440e-a527-d029d401ec2b",
"name": "test items3",
"qty": 1
}
]
},
{
"product_id": "2",
"product_name": "Polo",
"product_sku": "P01",
"items": [
{
"id": "625ad1bc-66c5-440e-a527-d029d401ec2b",
"name": "Box",
"qty": 1
},
{
"id": "625ad1bc-66c6-440e-a527-d029d401ec2b",
"name": "test items1",
"qty": 1
},
{
"id": "625ad1bc-66c7-440e-a527-d029d401ec2b",
"name": "test items2",
"qty": 1
},
{
"id": "625ad1bc-66c8-440e-a527-d029d401ec2b",
"name": "test items3",
"qty": 1
}
]
}
]
But This response is not my expected result, my expected result is like:
[
{
"product_id": "1",
"product_name": "Cardigan",
"pitems": [
{
"id": "625ad1bc-66c5-440e-a527-d029d401ec2b",
"name": "Box",
"qty": 1
},
{
"id": "625ad1bc-66c6-440e-a527-d029d401ec2b",
"name": "test items1",
"qty": 1
},
{
"id": "625ad1bc-66c7-440e-a527-d029d401ec2b",
"name": "test items2",
"qty": 1
}
]
},
{
"product_id": "2",
"product_name": "Polo",
"product_sku": "P01",
"items": [
{
"id": "625ad1bc-66c8-440e-a527-d029d401ec2b",
"name": "test items3",
"qty": 1
}
]
}
]
Can Anyone help me to solve my problem?
What does it mean to show detailed data?
the easy way is:
create 2 func like this:
func detail(id int)(result model.Struct)
{ return result }
func product()(result model.Struct_Result) {
for data.Next() {
// call func detail
data.Scan(&id, &product)
detailResult := detail(id)
// then put together with struct and mix append ()
outputLoop := model.Result{
"product_id": id,
"pitems": [
{
"id": detailResult.id,
"name": detailResult.name,
"qty": detailResult.qty
},
]
}
result = append(result,outputLoop)
}
return result
}
I have a Cosmos DB database with documents that have the following form:
{
"Id": "1",
"Price": 200,
"Properties": [
{
"Name": "Name1",
"Type": "Type1",
},
{
"Name": "Name2",
"Type": "Type2",
}
]
},
{
"Id": "2",
"Price": 500,
"Properties": [
{
"Name": "Name1",
"Type": "Type1",
},
{
"Name": "Name2",
"Type": "Type3",
}
]
},
{
"Id": "3",
"Price": 400,
"Properties": [
{
"Name": "Name1",
"Type": "Type2",
}
]
}
I would like to create a query that returns documents that satisfy multiple properties. E.g. I would like to retrieve the documents that have both properties of Type1 and Type2. The result should give me only the document with Id = 1.
SELECT c.Id
FROM c
WHERE ARRAY_CONTAINS(c.Properties, {'Type': 'Type1' }, true)
AND ARRAY_CONTAINS(c.Properties, {'Type': 'Type2' }, true)
I would like to know how to sort a collection in mule using Dataweave orderBy with multiple number of fields and also with ascending or descending order.
Here is the sample code(with example) that I created to demonstrate multiple orderby and sorting. Note:- By default, the order by is ascending order and to achieve the descending order, just reverse the result at the end by [-1..0].
%dw 1.0
%var inputPayload=[
{"name":"john",
"age": "12"
},
{"name":"john3",
"age": "15"
},
{"name":"john3",
"age": "14"
},
{"name":"john1",
"age": "13"
},
{"name":"john2",
"age": "14"
},
{"name":"john5",
"age": "17"
}
]
%output application/json
---
((inputPayload orderBy $.name) orderBy $.age)[-1..0]
Output Payload - [ {
"name": "john5",
"age": "17" }, {
"name": "john3",
"age": "15" }, {
"name": "john3",
"age": "14" }, {
"name": "john2",
"age": "14" }, {
"name": "john1",
"age": "13" }, {
"name": "john",
"age": "12" } ]
You have to use the OrderBy and concatenate operator for this. Giving an example below
payload orderBy ($.name ++ $.id)
I think the accepted answer just re-orders the entire array twice and only works for that particular example. If you use an example where the age a number instead of a string like so
{
"input": [
{
"name": "john",
"age": 12
},
{
"name": "john5",
"age": 7
},
{
"name": "john3",
"age": 15
},
{
"name": "john3",
"age": 14
},
{
"name": "john1",
"age": 13
},
{
"name": "john2",
"age": 14
}
]
}
then the output ends up in the wrong order for a multi-layer orderBy (it's the order you would expect if we just did orderBy age)
[
{
"name": "john3",
"age": 15
},
{
"name": "john3",
"age": 14
},
{
"name": "john2",
"age": 14
},
{
"name": "john1",
"age": 13
},
{
"name": "john",
"age": 12
},
{
"name": "john5",
"age": 7
}
]
whereas something like
flatten(((inputPayload orderBy $.name) groupBy $.name) pluck ($ orderBy $.age))[-1..0] gives
[
{
"name": "john5",
"age": 7
},
{
"name": "john3",
"age": 15
},
{
"name": "john3",
"age": 14
},
{
"name": "john2",
"age": 14
},
{
"name": "john1",
"age": 13
},
{
"name": "john",
"age": 12
}
]
so the overall orderBy is name and then within the same name the orderBy is age