好啦,JSONB 在 PostgreSQL 裡超強,可以拿來存很複雜的階層資料結構。但如果你想要改一下 JSONB 欄位裡的某個值怎麼辦?比如說換掉使用者的電話號碼,或是在 array 裡加一個新分類?聽起來很簡單,但 JSONB 不是 table,不能直接改某一格。要更新 JSON 物件的資料,我們要用一些特別的 function。今天的主角就是:
jsonb_set():可以根據你指定的「路徑」去改值或加值。jsonb_insert():可以在 JSON array 裡插入新元素。
用 jsonb_set() 更新資料
jsonb_set() 這個 function 可以改掉 JSONB 物件的一部分,或是加進去新的 key 跟 value。
基本語法
jsonb_set(target jsonb, path text[], new_value jsonb, create_missing boolean)
target— 你要更新的 JSONB 物件。path— 一個字串 array,代表你要改的 key 的路徑。new_value— 你想加進去或取代的值。create_missing— 布林值(TRUE 或 FALSE),決定要不要自動建立不存在的 key。
來看個簡單例子。假設我們有一個 users table,裡面有個 profile 欄位是 JSONB,存使用者的 profile。有個使用者要換電話號碼,怎麼做?
-- 建 table 並加資料
CREATE TABLE users (
id SERIAL PRIMARY KEY,
profile JSONB
);
INSERT INTO users (profile)
VALUES ('{"name": "奧托", "contact": {"phone": "+1-495-123-45-67"}}');
-- 更新電話號碼
UPDATE users
SET profile = jsonb_set(profile, '{contact,phone}', '"8-800-555-35-35"', FALSE)
WHERE id = 1;
-- 查查結果
SELECT profile FROM users WHERE id = 1;
結果:
{
"name": "奧托",
"contact": {
"phone": "8-800-555-35-35"
}
}
酷吧!我們把電話號碼改掉了!注意,key 的路徑是用字串 array '{contact,phone}' 來寫的。
加新 key
如果你要改的 key 不存在,可以把 create_missing = TRUE,這樣會自動幫你加:
UPDATE users
SET profile = jsonb_set(profile, '{address,city}', '"柏林"', TRUE)
WHERE id = 1;
-- 查查結果
SELECT profile FROM users WHERE id = 1;
結果:
{
"name": "奧托",
"contact": {
"phone": "8-800-555-35-35"
},
"address": {
"city": "柏林"
}
}
現在多了一個 address 欄位,超方便對吧?
用 jsonb_insert() 插入資料
jsonb_insert() 這個 function 是拿來在 JSONB 物件裡的 array 加新元素的。
基本語法
jsonb_insert(target jsonb, path text[], new_value jsonb, insert_after boolean)
target— 目標 JSONB 物件。path— 字串 array,代表你要插入的 array 路徑。new_value— 你要加進去的值。insert_after— 布林值。FALSE 會插在指定 index 前面,TRUE 則是後面。
來個例子。假設我們有個 table,profile 欄位裡有使用者的興趣 array。我們想在 array 裡加一個新興趣:
-- 先加點資料
UPDATE users
SET profile = jsonb_set(profile, '{interests}', '["運動", "音樂"]', TRUE)
WHERE id = 1;
-- 把新興趣 "程式設計" 插到最前面
UPDATE users
SET profile = jsonb_insert(profile, '{interests,0}', '"程式設計"', FALSE)
WHERE id = 1;
-- 查查結果
SELECT profile FROM users WHERE id = 1;
結果:
{
"name": "奧托",
"contact": {
"phone": "8-800-555-35-35"
},
"address": {
"city": "柏林"
},
"interests": [
"程式設計",
"運動",
"音樂"
]
}
常見問題跟怎麼避免
用 jsonb_set() 跟 jsonb_insert() 有時候會有點 tricky,下面這些要注意:
- key 路徑寫錯。 如果你路徑寫錯,或是要改的元素不存在但沒設
create_missing=TRUE,會出錯或啥都沒改。一定要先確認你的 JSON 結構。 - 資料型態不對。 記得
new_value一定要是 JSONB 型態。如果你要加字串,記得要用雙引號包起來('"值"')。 - 資料被覆蓋。 如果你直接改 array 沒用對 function,可能會把舊資料洗掉。要加新元素就用
jsonb_insert(),比較安全。
錯誤範例:
-- 錯誤:路徑寫錯
UPDATE users
SET profile = jsonb_set(profile, '{contacts}', '"新聯絡方式"', FALSE)
WHERE id = 1;
這會出錯,因為 profile 裡沒有 contacts 這個 key,而且 create_missing 設成 FALSE。
怎麼避免:
-- 設 create_missing = TRUE
UPDATE users
SET profile = jsonb_set(profile, '{contacts}', '"新聯絡方式"', TRUE)
WHERE id = 1;
這些東西實際上會用在哪?
用 JSONB 不是在玩,是很多現代應用都超需要的技能。舉幾個實際例子:
- 存使用者設定。 JSONB 超適合存動態資料結構,像是每個人都不一樣的 app 設定。
- 跟外部 API 整合。 JSONB 很方便拿來存 REST API 回傳的原始 JSON 物件。
- 大數據分析。 巢狀 JSON 結構很適合存 IoT 資料、log 或 analytics。
這樣我們的 JSON 物件更新入門就先到這啦。你現在已經會怎麼插入、更新、加資料到 JSONB,也知道怎麼避開常見錯誤。下堂課我們會講怎麼合併 JSONB 物件,還有更進階的用法喔!
GO TO FULL VERSION