The schema is... problematic. You should really use jsonb instead of jsonb[] since json supports arrays out of the box.
Anyway, if the schema is as it is, then you can utilize something like this:
select distinct tmp2.id
from (
select
tmp1.id,
jsonb_array_elements(tmp1.pets->'toys') as toys
from (
select
id,
unnest(pets) as pets
from users
) tmp1
) tmp2
where jsonb_extract_path_text(tmp2.toys, 'color') = 'red'
(it can be probably written in a more readable way by utilizing with instead of nesting selects)
Explanation:
unnest will turn an internal array into separate rows.
jsonb_array_elements does the same thing, except it operates on jsonb arrays (we have to unwrap the internal toys arrays as well).
jsonb_extract_path_text retrieves the internal text stored under key.
Note that the query assumes the specific format you have. I didn't test the query against other json variants.
jsonb[]instead ofjsonbsimply? Json does support arrays, an array of jsons is an unnecessary complication. With this approach you probably have tounnestthe table first.jsonb[]almost never makes sense. It's better to usejsonband store a JSON array in it (not an array of jsonb)unnestfunction... that seems useful