Postgres:无法使 JSONB_PATH_EXISTS 正常工作
Postgres : can't make JSONB_PATH_EXISTS work correctly
我正在努力使用 JSONB_PATH_EXISTS
Postgres 函数
我正在使用 PG 12 并遵循此文档:https://www.postgresql.org/docs/12/functions-json.html
使用以下请求(在 DBFiddle 上测试:https://dbfiddle.uk/?rdbms=postgres_12&fiddle=d5aa984182852438c6f71cf5fa70324e):
select
json
from (
select '{
"fields": {
"foo": true,
"number": 3,
"listnb": [3, 4],
"listenb2": ["3", "4"],
"txt": "hello how are you",
"listtxt": ["hello","how","are", "you", "3"],
"nullval": null
}
}'::jsonb as json
) t
where 1=1
-- Works with 'strict'
AND JSONB_PATH_EXISTS(json -> 'fields' -> 'listtxt', 'strict $ ? (@.type() == "array")')
-- Doesn't work without 'strict'. Why ?
--AND JSONB_PATH_EXISTS(json -> 'fields' -> 'listtxt', '$ ? (@.type() == "array")')
-- Can't add a nested condition on an array element value (syntax error)
--AND JSONB_PATH_EXISTS(json -> 'fields' -> 'listtxt', 'strict $ ? (@.type() == "array" && @[*] ? (@ == "how"))')
;
#1 - 如果没有 strict
模式
,我无法使用 type() 函数
这可能与 lax 模式自动展开数组有关,但文档明确指出调用 type()
函数时未完成:
The lax mode facilitates matching of a JSON document structure and path expression if the JSON data does not conform to the expected schema. [...] Automatic unwrapping is not performed only when:
- The path expression contains type() or size() methods that return the type and the number of elements in the array, respectively.
- [...]
所以我不明白为什么我们的结果不同
#2 我无法使用嵌套条件(示例请求中的第 3 AND
)
根据文档中的示例,语法看起来不错,但我有一个我不理解的语法错误。
感谢您的帮助
如果您将完整的 JSON 值传递给该函数,则可以执行以下操作:
where jsonb_path_exists(json, '$ ? (@.fields.listtxt.type() == "array")')
但是我可能会简单地使用 jsonb_typeof()
而无需路径查询
where jsonb_typeof(json -> 'fields' -> 'listtxt') = 'array'
我正在努力使用 JSONB_PATH_EXISTS
Postgres 函数
我正在使用 PG 12 并遵循此文档:https://www.postgresql.org/docs/12/functions-json.html
使用以下请求(在 DBFiddle 上测试:https://dbfiddle.uk/?rdbms=postgres_12&fiddle=d5aa984182852438c6f71cf5fa70324e):
select
json
from (
select '{
"fields": {
"foo": true,
"number": 3,
"listnb": [3, 4],
"listenb2": ["3", "4"],
"txt": "hello how are you",
"listtxt": ["hello","how","are", "you", "3"],
"nullval": null
}
}'::jsonb as json
) t
where 1=1
-- Works with 'strict'
AND JSONB_PATH_EXISTS(json -> 'fields' -> 'listtxt', 'strict $ ? (@.type() == "array")')
-- Doesn't work without 'strict'. Why ?
--AND JSONB_PATH_EXISTS(json -> 'fields' -> 'listtxt', '$ ? (@.type() == "array")')
-- Can't add a nested condition on an array element value (syntax error)
--AND JSONB_PATH_EXISTS(json -> 'fields' -> 'listtxt', 'strict $ ? (@.type() == "array" && @[*] ? (@ == "how"))')
;
#1 - 如果没有 strict
模式
这可能与 lax 模式自动展开数组有关,但文档明确指出调用 type()
函数时未完成:
The lax mode facilitates matching of a JSON document structure and path expression if the JSON data does not conform to the expected schema. [...] Automatic unwrapping is not performed only when:
- The path expression contains type() or size() methods that return the type and the number of elements in the array, respectively.
- [...]
所以我不明白为什么我们的结果不同
#2 我无法使用嵌套条件(示例请求中的第 3 AND
)
根据文档中的示例,语法看起来不错,但我有一个我不理解的语法错误。
感谢您的帮助
如果您将完整的 JSON 值传递给该函数,则可以执行以下操作:
where jsonb_path_exists(json, '$ ? (@.fields.listtxt.type() == "array")')
但是我可能会简单地使用 jsonb_typeof()
而无需路径查询
where jsonb_typeof(json -> 'fields' -> 'listtxt') = 'array'