我正在使用 PostgreSQL 9.6,我有一个名为“ItemDbModel”的表,其中包含两列,如下所示:
No integer,
Content jsonb
假设我放了很多记录,例如:
"No": 2, {"obj":"x","Item": {"Name": "BigDog", "Model": "NamedHusky", "Spec":"red dog"}}
"No": 4, {"obj":"x","Item": {"Name": "MidDog", "Model": "NamedPeppy", "Spec":"no hair"}}
"No": 5, {"obj":"x","Item": {"Name": "BigCat", "Model": "TomCat", "Spec":"blue color"}}
如何查询表:
- 记录“Content.Item.Name”包含“Dog”并且“Content.Item.Spec”包含“red”。
- “Content.Item.Name”包含“Dog”的记录或“Content.Item.Spec”包含“red”。
- 记录“Content.Item”中任何 json 字段包含“dog”的位置。
然后按“Content.Item.Name.length”排序?
谢谢!
最佳答案
您应该熟悉 JSON Functions and Operators .
-- #1
select *
from example
where content->'Item'->>'Name' ilike '%dog%'
and content->'Item'->>'Spec' ilike '%red%'
-- #2
select *
from example
where content->'Item'->>'Name' ilike '%dog%'
or content->'Item'->>'Spec' ilike '%red%'
-- #3
select distinct on(no) t.*
from example t,
lateral jsonb_each_text(content->'Item')
where value ilike '%dog%';
-- and
select *
from example t
order by length(content->'Item'->>'Name');
Postgres 12 引入了实现 SQL/JSON 路径语言的新功能。使用 jsonpath
的替代查询可能如下所示:
-- #1
select *
from example
where jsonb_path_exists(
content,
'$ ? ($.Item.Name like_regex "dog" flag "i" && $.Item.Spec like_regex "red" flag "i")');
-- #2
select *
from example
where jsonb_path_exists(
content,
'$ ? ($.Item.Name like_regex "dog" flag "i" || $.Item.Spec like_regex "red" flag "i")');
-- #3
select *
from example
where jsonb_path_exists(
content,
'$.Item.* ? (@ like_regex "dog" flag "i")');
前两个查询与前面的查询基本相似,->
语法看起来比 jsonpath
语法更简单、更令人愉快。应特别注意第三个查询,它使用通配符,因此无需使用昂贵的函数 jsonb_each_text ()
并且速度应该明显更快。
阅读文档:
关于json - Postgresql 查询嵌套 JSONB 字段中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42130740/