簡體   English   中英

如何在Postgresql中選擇和更新JSON數組元素?

[英]How do I select and update a JSON array element in Postgresql?

我正在使用9.6版本。 我的文檔看起來像這樣:

{
    "name" : "John Doe", 
    "phones" : [
        {
            "type" : "mobile", 
            "number" : "555-555-0000",
            "deleted": false
        }, 
        {
            "type" : "home", 
            "number" : "555-555-0001",
            "needsUpdated" : true
        }, 
        {
            "type" : "work", 
            "number" : "555-555-0002"
        }
    ]
}

我創建了這樣的:

create table t_json (c_json json not null);

insert into t_json (c_json) values ('{"name":"John Doe","phones": [{"type":"mobile","number":"555-555-0000"},{"type":"home","number":"555-555-0001"},{"type": "work","number": "555-555-0002"}]}');

insert into t_json (c_json) values ('{"name":"Jane Dane","phones": [{"type":"mobile","number":"555-555-0030"},{"type":"home","number":"555-555-0020"},{"type": "work","number": "555-555-0010"}]}');

現在我想弄清楚如何A ,選擇名為John Doe的行,並將他的手機號碼更新為“555-555-0003”。

從這里Postgresql 9.6文檔我發現我可以查詢正確的文檔,如下所示:

select c_json from t_json where c_json->>'name' = 'John Doe';

但我沒有看到如何按類型選擇手機陣列中的正確子文檔,並更新數值。 誰能幫我嗎?

編輯

我需要假設子文檔有額外的值並且不一致。 所以我在上面添加了一些。 我非常確定此時無法在沒有數據丟失的情況下進行此更新。

如何按類型在手機陣列中選擇正確的子文檔?

如果您想獲取電話號碼,請使用此號碼。 相應的文件是https://www.postgresql.org/docs/9.6/static/queries-table-expressions.html#QUERIES-LATERAL

SELECT c_json ->> 'name', phones.type, phones.number
    FROM t_json
    CROSS JOIN json_to_recordset(c_json -> 'phones')
        AS phones("type" TEXT, "number" TEXT);

如果您想通過電話號碼搜索,這可以:

SELECT * FROM t_json
    WHERE (c_json -> 'phones')::JSONB @>
        '[{"type":"mobile","number":"555-555-0000"}]'::JSONB;

如何更新數值?

正如評論中提到的,有一個類似的問題, 如何修改新的PostgreSQL JSON數據類型中的字段?

還有其他方法可以做到這一點,比如

UPDATE t_json SET c_json = newvalue FROM (
    SELECT to_json(updated) AS newvalue FROM (
        SELECT c_json ->> 'name' as "name",
            json_agg(json_build_object('type', phones.type, 'number',
                CASE phones.type WHEN 'mobile' THEN '555-555-0003' ELSE phones.number END)
            ) AS phones
    FROM t_json
    CROSS JOIN json_to_recordset(c_json -> 'phones')
        AS phones("type" TEXT, "number" TEXT)
    WHERE c_json->>'name' = 'John Doe'
    GROUP BY name
    ) as updated
) AS sub WHERE c_json ->> 'name' = 'John Doe';

暫無
暫無

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

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