简体   繁体   English

查询 JSON 类型内的数组元素

[英]Query for array elements inside JSON type

I'm trying to test out the json type in PostgreSQL 9.3.我正在尝试测试 PostgreSQL 9.3 中的json类型。
I have a json column called data in a table called reports .我在名为reports的表中有一个名为datajson列。 The JSON looks something like this: JSON 看起来像这样:

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

I would like to query the table for all reports that match the 'src' value in the 'objects' array.我想在表中查询与 'objects' 数组中的 'src' 值匹配的所有报告。 For example, is it possible to query the DB for all reports that match 'src' = 'foo.png' ?例如,是否可以在数据库中查询匹配'src' = 'foo.png'所有报告? I successfully wrote a query that can match the "background" :我成功地编写了一个可以匹配"background"的查询:

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

But since "objects" has an array of values, I can't seem to write something that works.但是由于"objects"有一个值数组,我似乎无法写出有效的东西。 Is it possible to query the DB for all reports that match 'src' = 'foo.png' ?是否可以在数据库中查询所有匹配'src' = 'foo.png' I've looked through these sources but still can't get it:我已经查看了这些来源,但仍然无法获得:

I've also tried things like this but to no avail:我也试过这样的事情,但无济于事:

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

I'm not an SQL expert, so I don't know what I am doing wrong.我不是 SQL 专家,所以我不知道我做错了什么。

jsonb in Postgres 9.4+ jsonb Postgres里9.4+

You can use the same query as below, just with jsonb_array_elements() .可以使用与下面相同的查询,只需使用jsonb_array_elements()

But rather use the jsonb "contains" operator @> in combination with a matching GIN index on the expression data->'objects' :而是将jsonb “包含”运算符@>与表达式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"}]';

Since the key objects holds a JSON array , we need to match the structure in the search term and wrap the array element into square brackets, too.由于键objects包含一个 JSON数组,我们需要匹配搜索词中的结构并将数组元素也包装在方括号中。 Drop the array brackets when searching a plain record.搜索普通记录时删除数组括号。

More explanation and options:更多解释和选项:

json in Postgres 9.3+ Postgres 中的json 9.3+

Unnest the JSON array with the function json_array_elements() in a lateral join in the FROM clause and test for its elements: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<>fiddle here db<> 在这里摆弄
Old sqlfiddle旧的sqlfiddle

Or, equivalent for just a single level of nesting:或者,等效嵌套的只是一个单一的水平:

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

->> , -> and #> operators are explained in the manual. ->>->#>运算符在手册中进行了解释。

Both queries use an implicit JOIN LATERAL .这两个查询都使用隐式JOIN LATERAL

Closely related:密切相关:

Create a table with column as type json创建一个列为 json 类型的表

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

Now let's insert json data现在让我们插入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}');

Now let's make some queries to fetch data现在让我们做一些查询来获取数据

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

You might have noticed that the results comes with inverted comma( " ) and brackets ([ ])您可能已经注意到结果带有引号 (") 和括号 ([])

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

Now to retrieve only the values just use ->>现在只检索值只需使用->>

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';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM