Query for array elements inside JSON type

女生的网名这么多〃 提交于 2019-11-26 06:49:40

json in Postgres 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:

WITH reports(data) AS (
   VALUES ('{"objects":[{"src":"foo.png"}, {"src":"bar.png"}]
           , "background":"background.png"}'::json)
   ) 
SELECT *
FROM   reports r, json_array_elements(r.data#>'{objects}') obj
WHERE  obj->>'src' = 'foo.png';

The CTE (WITH query) just substitutes for a table reports.
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.

SQL Fiddle.

Closely related answer:

jsonb in Postgres 9.4+

Use the equivalent jsonb_array_elements().

Better yet, use the new "contains" operator @> (best in combination with a matching GIN index on the expression data->'objects'):

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. Drop the array brackets when searching a plain record.

Detailed explanation and more options:

Create a table with column as type json

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

Now let's insert json data

# 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';
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!