I’m trying to run the following query, which unless I’m misunderstanding the documentation looks as like it should be possible.
SELECT id, profile
FROM end_user
WHERE profile @? '$.first_segment_exited_at ? (@.datetime() < "2023-05-25".datetime())'::jsonpath;
This is the documentation which leads me to think I should be able to achieve this:
string . datetime() → datetime_type (see note)
Date/time value converted from a string
jsonb_path_query(‘["2015-8-1", "2015-08-12"]’, ‘$[*] ? (@.datetime() <
"2015-08-2".datetime())’) → "2015-8-1"
Example profile data, note the dates are valid ISO format;
{
"first_segment_exited_at": "2023-05-22T03:09:37.825Z",
}
The following query returns results, but I’m keen on switching to jsonpath syntax in order to utilize an index
select id, profile
from end_user
where '2023-05-25'::timestamptz > (profile->>'first_segment_exited_at')::timestamptz
I’m running Postgres v14.
2
Answers
Illegal JSON datetime format in the table column. This works:
fiddle
Row 3 is the only one with legal format.
(The filter expression needs to be valid, too.)
You didn’t get an error message because, quoting the manual:
To debug input strings, test with a function that doesn’t suppress the error. Like
jsonb_path_query_first()
:But this one flies:
Also, you can supply a template pattern to the
.datetime()
method like Laurenz demonstrates in his added answer. (More obstacles ahead …)The problem is that your date is not in a format that
datetime()
recognizes, and you have to specify a template string withdatetime()
. Use the followingjsonpath
:I had to use the (I believe undocumented) PostgreSQL extension of double quoted literal format strings to match the
T
andZ
in the string.