postgresql 查询JSON类型中的数组元素

db2dz4w8  于 2023-02-08  发布在  PostgreSQL
关注(0)|答案(2)|浏览(593)

我正在测试PostgreSQL 9.3中的json类型。
我在一个名为reports的表中有一个名为datajson列。

{
  "objects": [
    {"src":"foo.png"},
    {"src":"bar.png"}
  ],
  "background":"background.png"
}

我想查询表中与'objects'数组中的'src'值匹配的所有报表。例如,是否可以查询DB中与'src' = 'foo.png'匹配的所有报表?我成功地编写了一个可以匹配"background"的查询:

SELECT data AS data FROM reports where data->>'background' = 'background.png'

但是由于"objects"有一个数组值,我似乎无法编写出有效的代码。是否可以查询数据库中所有与'src' = 'foo.png'匹配的报表?我已经查看了这些源代码,但仍然无法获得:

我也尝试过类似的事情,但没有效果:

SELECT json_array_elements(data->'objects') AS data from reports
WHERE  data->>'src' = 'foo.png';

我不是SQLMaven,所以我不知道我做错了什么。

1tuwyuhd

1tuwyuhd1#

jsonb(在Postgres 9.4以上版本中)

您 * 可以 * 使用与下面相同的查询,只是使用jsonb_array_elements()
而是将jsonb "contains"运算符@>与表达式data->'objects'上的匹配GIN索引结合使用:

CREATE INDEX reports_data_gin_idx ON reports
USING gin ((data->'objects') jsonb_path_ops);

SELECT * FROM reports WHERE data->'objects' @> '[{"src":"foo.png"}]';

由于键objects包含一个JSON * array *,我们需要匹配搜索项中的结构,并将数组元素也括在方括号中,搜索普通记录时请去掉数组括号。
更多说明和选项:

  • 用于在JSON数组中查找元素的索引

json(在Postgres 9.3+中)

FROM子句的横向连接中使用函数json_array_elements()取消嵌套JSON数组,并测试其元素:

SELECT data::text, obj
FROM   reports r, json_array_elements(r.data#>'{objects}') obj
WHERE  obj->>'src' = 'foo.png';
  • db〈〉小提琴here *

老SQLF
或者,对于仅 * 单 * 级嵌套,等效于:

SELECT *
FROM   reports r, json_array_elements(r.data->'objects') obj
WHERE  obj->>'src' = 'foo.png';

->>->#>操作符在手册中有解释。
两个查询都使用隐式JOIN LATERAL
密切相关的:

  • 查询JSON列中数组的元素
7gcisfzg

7gcisfzg2#

创建一个列类型为json的表

CREATE TABLE friends ( id serial primary key, data jsonb);

现在我们插入json数据

INSERT INTO friends(data) VALUES ('{"name": "Arya", "work": ["Improvements", "Office"], "available": true}');
INSERT INTO friends(data) VALUES ('{"name": "Tim Cook", "work": ["Cook", "ceo", "Play"], "uses": ["baseball", "laptop"], "available": false}');

现在,让我们执行一些查询来获取数据

select data->'name' from friends;
select data->'name' as name, data->'work' as work from friends;

您可能已经注意到结果以列表形式出现

name    |            work            
------------+----------------------------
 "Arya"     | ["Improvements", "Office"]
 "Tim Cook" | ["Cook", "ceo", "Play"]
(2 rows)

现在,要仅检索值,只需使用->>

select data->>'name' as name, data->'work'->>0 as work from friends;
select data->>'name' as name, data->'work'->>0 as work from friends where data->>'name'='Arya';

相关问题