对嵌套 JSONB 字段中的对象进行 Postgresql 查询



我正在使用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"}}

如何查询表中的以下信息:

  1. "Content.Item.Name"包含"Dog">"Content.Item.Spec"包含"red"的记录。
  2. "Content.Item.Name"包含"Dog">"Content.Item.Spec"包含"red"的记录。
  3. "Content.Item"中的任何 json 字段包含"dog"的记录。

并按"Content.Item.Name.length"排序?

谢谢!

您应该熟悉 JSON 函数和运算符。

-- #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 (),并且应该明显更快。

阅读文档:

  • SQL/JSON 路径语言
  • jsonpath 类型

最新更新