I have a PostgreSQL database with a JSONB column named properties
. I’m trying to create a query that matches all elements with a value inside properties
that matches a certain value.
Currently, I’m using a combination of jsonb_path_exists
and like_regex
, like this:
SELECT id FROM mytable WHERE jsonb_path_exists(properties, '$.data.** ? (@ like_regex "(?i)Foo.*")');
This works well for string values, but the problem arises with non-string elements. For example, if I want to search for an integer value, like_regex
returns false every time.
Is there a way to fix this, such as using something like @.toString()
?`
If you want to try it yourself
SELECT jsonb_path_exists('{"data": {"foo1": 344, "foo2": "Tata"}}', '$.data.** ? (@ like_regex "(?i)344.*")');
3
Answers
I think you could use this query for your purpose
To break it down for you,
->
operator navigates through the JSON and->>
extracts the value as text.strict $.data.**
object
s andarray
s along the way to get only the bottom scalars.jsonb
wrapping from around the value with#>>'{}'
(empty path accessor). Casting straight totext
would otherwise add quotes.demo at db-fiddle
The mismatch from row zero got skipped:
As pointed out by @Bergi, this might be useful for 3 weeks tops, until November 14th 2024 when PostgreSQL 17 will bring more JSON type conversion methods:
Postgres 17 (currently in development) will (prospectively) come with a
@.string()
method in JSON path that does exactly this: "String value converted from a JSON boolean, number, string, or datetime".