I want to filter JSON objects in array by its multi-attributes. Below is example data and basic filters:
with data (id, extra_info) as (
values
(1, '[{"name": "class", "value": 3}, {"name": "dept", "value": "No. 2"}, {"name": "batch", "value": 20070102}]'::jsonb),
(2, '[{"name": "class", "value": 2}, {"name": "dept", "value": "No. 3"}, {"name": "batch", "value": 20081123}]'::jsonb),
(3, '[{"name": "class", "value": 3}, {"name": "dept", "value": "No. 1"}]'::jsonb)
)
select *
from data
where extra_info @> '[{"name": "class", "value": 3}]'::Jsonb and
extra_info @> '[{"name": "batch", "value": 20070102}]'::Jsonb
All objects in JSON array has same structure. But now I want to get JSON objects with "name"="class" and "value" > 2 , how can I do it? The "value" attribute may be string, int, float and boolean. Thanks!
You can use jsonb_array_elements
in a subquery:
select d.* from data d where exists (select 1 from jsonb_array_elements(d.extra_info) v
where ((v.value -> 'name')::text = '"class"' and (v.value -> 'value')::text::int > 2) or ((v.value -> 'name')::text = '"batch"' and (v.value -> 'value')::text::int > 20071010))
You can use a JSON path expression:
and extra_info @? '$[*] ? (@.name == "class" && @.value > 2)'
Note that this won't work if value isn't a number (as shown in the sample data) inside the JSON
test value be boolean or string. number is quite simple.
WITH data (
id,
extra_info
) AS (
VALUES (1, '[{"name": "class", "value": 3}, {"name": "dept", "value": "No. 2"}, {"name": "batch", "value": "test_str"}]'::jsonb),
(2, '[{"name": "class", "value": true}, {"name": "dept", "value": "No. 3"}, {"name": "batch", "value": 20081123}]'::jsonb),
(3, '[{"name": "class", "value": 3}, {"name": "dept", "value": "No. 1"}]'::jsonb))
SELECT
*
FROM
data
WHERE
jsonb_path_exists(extra_info, '$[*] ? (@.name == $var1 && @.value == $var2)', vars => '{"var1": "class", "var2": true}')
OR jsonb_path_exists(extra_info, '$[*] ? (@.name == $var1 && @.value == $var2)', vars => '{"var1": "batch", "var2": "test_str"}');
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.