Обсуждение: jsonb : find row by array object attribute
With a table like this:
Table "public.x"
Column | Type | Modifiers
--------+-------+-----------
j | jsonb |
and data like this:
j
--------------------------------------------------
{"a": 1, "people": [{"id": 2002}, {"id": 2004}]}
{"a": 3, "people": [{"id": 2003}, {"id": 2005}]}
(2 rows)
I'd like to be able to find any row with a particular people id
attribute.
I can do it explitly like this:
select * from x where j->'people'->0->'id' = '2003'::jsonb;
j
--------------------------------------------------
{"a": 3, "people": [{"id": 2003}, {"id": 2005}]}
(1 row)
but that doesn't help if I need to find if any person matches the id
attribute I'm looking for.
I can get part of the way by searching like this:
=> select * from (
select jsonb_array_elements(j #>'{people}') as jae from x
) y
where jae->'id' = '2002'::jsonb;
jae
--------------
{"id": 2002}
(1 row)
but I can't work out how to return the whole row containing a desired
people id value.
Thanks for any help
Rory
Rory Campbell-Lange <rory@campbell-lange.net> writes:
> ... I can't work out how to return the whole row containing a desired
> people id value.
Something like this, maybe?
=# select * from x where
'2003'::jsonb in (select jsonb_array_elements(j #>'{people}')->'id');
j
--------------------------------------------------
{"a": 3, "people": [{"id": 2003}, {"id": 2005}]}
(1 row)
It's not too efficient though :-(
regards, tom lane
>>>>> "Rory" == Rory Campbell-Lange <rory@campbell-lange.net> writes:
Rory> and data like this:
Rory> j
Rory> --------------------------------------------------
Rory> {"a": 1, "people": [{"id": 2002}, {"id": 2004}]}
Rory> {"a": 3, "people": [{"id": 2003}, {"id": 2005}]}
Rory> (2 rows)
Rory> I'd like to be able to find any row with a particular people id
Rory> attribute.
where j @> '{"people":[{"id":2003}]}'
(meaning: j contains a key "people" whose value is an array containing
an element {"id":2003})
Since @> can use GIN indexes, you should usually try and find a search
condition using it before resorting to playing with -> or expanding out
array values.
--
Andrew (irc:RhodiumToad)
>>>>> "Andrew" == Andrew Gierth <andrew@tao11.riddles.org.uk> writes:
>>>>> "Rory" == Rory Campbell-Lange <rory@campbell-lange.net> writes:
Rory> and data like this:
Rory> j
Rory> --------------------------------------------------
Rory> {"a": 1, "people": [{"id": 2002}, {"id": 2004}]}
Rory> {"a": 3, "people": [{"id": 2003}, {"id": 2005}]}
Rory> (2 rows)
Rory> I'd like to be able to find any row with a particular people id
Rory> attribute.
Andrew> where j @> '{"people":[{"id":2003}]}'
Andrew> (meaning: j contains a key "people" whose value is an array
Andrew> containing an element {"id":2003})
or to be more precise: j is an object containing a key "people" whose
value is an array containing an element which is an object containing a
key "id" with value 2003
i.e. {"a":3, "people": [{"id":2003,"blah":123},{"id":2004}]} would
match the condition too.
--
Andrew (irc:RhodiumToad)