我想我正在尝试一些简单的方法,但是下班后我无法正常工作。我有一个包含标签列的表,它是一个jsonb数组,看起来像这样:
{"{\"name\": \"e-commerce\", \"weight\": 400}","{\"name\": \"management\", \"weight\": 200}","{\"name\": \"content management\", \"weight\": 200}"}
现在,我想编写一个查询,当名称与搜索字符串匹配时,该查询将完整的对象返回给我。到目前为止,我想到了这个:
SELECT * FROM data
WHERE tags is not null
AND EXISTS(
SELECT FROM data ad WHERE (ad.tags -> 'name' ->> 'education')::text
);
但是我得到这个错误:
[42883] ERROR: operator does not exist: jsonb[] -> unknown Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
我不确定应该在哪里进行类型转换以及这是否真的是问题。
如果要将每个匹配的对象放在单独的行上,则可以用于jsonb_array_elements()
取消嵌套对象数组的嵌套,然后进行过滤:
select o.obj
from data d
cross join lateral jsonb_array_elements(d.tags) o(obj)
where o.obj ->> 'name' = 'education'
在您具有JSONB数组的情况下有效(因此data的数据类型为jsonb
)。
另一方面,如果您有一个json对象数组(so:)jsonb[]
,则可以unnest
改为:
select o.obj
from data d
cross join lateral unnest(d.tags) o(obj)
where o.obj ->> 'name' = 'education'
请注意,当两个对象在同一数组中匹配时,这将生成两行。如果只需要一行,则可以使用exists
:
select o.obj
from data d
where exists (
select 1 from unnest(d.tags) o(obj) where o.obj ->> 'name' = 'education'
)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句