簡體   English   中英

查詢 JSON 類型內的數組元素

[英]Query for array elements inside JSON type

我正在嘗試測試 PostgreSQL 9.3 中的json類型。
我在名為reports的表中有一個名為datajson列。 JSON 看起來像這樣:

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

我想在表中查詢與 'objects' 數組中的 'src' 值匹配的所有報告。 例如,是否可以在數據庫中查詢匹配'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';

我不是 SQL 專家,所以我不知道我做錯了什么。

jsonb Postgres里9.4+

可以使用與下面相同的查詢,只需使用jsonb_array_elements()

而是將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"}]';

由於鍵objects包含一個 JSON數組,我們需要匹配搜索詞中的結構並將數組元素也包裝在方括號中。 搜索普通記錄時刪除數組括號。

更多解釋和選項:

Postgres 中的json 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<> 在這里擺弄
舊的sqlfiddle

或者,等效嵌套的只是一個單一的水平:

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

->>->#>運算符在手冊中進行了解釋。

這兩個查詢都使用隱式JOIN LATERAL

密切相關:

創建一個列為 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';

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM