正如已经指出的那样,你尝试使用的?|
是纯PostgreSQL中的一个运算符,但在当前实现的JSONPath中并不支持,因此不能在这种表达式中使用它。此外,在表达式中也不能使用数组或对象字面量,所以["5","7"]
也无法在此处使用。
如果你有一个jsonb
对象,并想要与另一个对象进行比较,你可以将整个对象作为变量传递到JSONPath表达式中。@?
操作符不允许这样做,但jsonb_path_exists()
函数可以做到这一点。一旦两个对象都在JSONPath表达式中,它们都可以使用[*]
访问器:
select jsonb_path_exists(
'{"id1": ["5"], "id2": ["5"],
"id3": ["cc","dd"],
"id4": "15", "id5": "11",
"id6": "2", "id7": ["12","18"]
}'::jsonb,
'$.id2[*]?(@==$var.id2[*])',
'{"var":{"id2":["5","7"]}}'::jsonb
);
结果显示为 t
,表示存在匹配项。
或者,你也可以直接将其合并到原始jsonb对象中:
select jsonb_path_exists(
'{"id1": ["5"], "id2": ["5"],
"id3": ["cc","dd"],
"id4": "15", "id5": "11",
"id6": "2", "id7": ["12","18"]
}'::jsonb || '{"var":{"id2":["5","7"]}}'::jsonb,
'$.id2[*]?(@==$var.id2[*])'
);
同样得到结果为 t
。
另外,如果你只想检查某个键值对应的数组是否包含特定的多个元素,可以使用常规的->
操作符获取该键,并直接结合?|
操作符以及text[]
数组:
select
' {
"id1": ["5"], "id2": ["5"],
"id3": ["cc","dd"],
"id4": "15", "id5": "11",
"id6": "2", "id7": ["12","18"]
}'::jsonb -> 'id2' ?| '{5,7}'
结果显示为 t
,表示"id2"数组包含了'5'或'7'。
在线演示示例