Check if a Postgres JSON array contains a string Check if a Postgres JSON array contains a string postgresql postgresql

Check if a Postgres JSON array contains a string


As of PostgreSQL 9.4, you can use the ? operator:

select info->>'name' from rabbits where (info->'food')::jsonb ? 'carrots';

You can even index the ? query on the "food" key if you switch to the jsonb type instead:

alter table rabbits alter info type jsonb using info::jsonb;create index on rabbits using gin ((info->'food'));select info->>'name' from rabbits where info->'food' ? 'carrots';

Of course, you probably don't have time for that as a full-time rabbit keeper.

Update: Here's a demonstration of the performance improvements on a table of 1,000,000 rabbits where each rabbit likes two foods and 10% of them like carrots:

d=# -- Postgres 9.3 solutiond=# explain analyze select info->>'name' from rabbits where exists (d(# select 1 from json_array_elements(info->'food') as foodd(#   where food::text = '"carrots"'d(# ); Execution time: 3084.927 msd=# -- Postgres 9.4+ solutiond=# explain analyze select info->'name' from rabbits where (info->'food')::jsonb ? 'carrots'; Execution time: 1255.501 msd=# alter table rabbits alter info type jsonb using info::jsonb;d=# explain analyze select info->'name' from rabbits where info->'food' ? 'carrots'; Execution time: 465.919 msd=# create index on rabbits using gin ((info->'food'));d=# explain analyze select info->'name' from rabbits where info->'food' ? 'carrots'; Execution time: 256.478 ms


You could use @> operator to do this something like

SELECT info->>'name'FROM rabbitsWHERE info->'food' @> '"carrots"';


Not smarter but simpler:

select info->>'name' from rabbits WHERE info->>'food' LIKE '%"carrots"%';