You can use the json
/ jsonb
containment operator @>
.
Since your JSON array seems to contain only numbers, the simple syntax works:
SELECT *
FROM tbl
WHERE collection @> '3'; -- single quotes required!
If you omit the quotes, Postgres resolves the numeric literal to integer
and doesn't find an operator for json @> integer
.
With quotes, the string literal is resolved to json
/ jsonb
respectively (containing the JSON primitive type number) derived from the context, and it works.
This works just as well, and may be preferable:
SELECT *
FROM tbl
WHERE collection @> '[3]';
Now, the right operand resolves to json
/ jsonb
containing the JSON primitive type array - containing a single number.
This also works for objects as array element types, which would not work without the array wrapper.
To make this fast, use the type jsonb
rather than json
because that enjoys index support. Either with the default operator class jsonb_ops
(default does not have to be spelled out):
CREATE INDEX tbl_jsb_idx ON tbl USING GIN (collection);
Or with the more specialized (but also more efficient) operator class jsonb_path_ops
(non-default has to be spelled out):
CREATE INDEX tbl_jsb_idx ON tbl USING GIN (collection jsonb_path_ops);
See: