Điều này có thể thực hiện được bằng cách tạo lại mảng json trên mỗi bản cập nhật.
SQL để tạo bảng và chèn dữ liệu mẫu:
CREATE TABLE test_table(
id BIGSERIAL PRIMARY KEY ,
game TEXT,
players JSONB
);
INSERT INTO test_table(game, players)
VALUES
('chess', '[{"name": "Joe", "role": "admin"}, {"name": "Mike", "role": "user"}]'),
('football', '[{"name": "Foo", "role": "user"}, {"name": "Bar", "role": "user"}]');
Dữ liệu được chèn:
+----+----------+----------------------------------------------------------------------+
| id | game | players |
+----+----------+----------------------------------------------------------------------+
| 1 | chess | [{"name": "Joe", "role": "admin"}, {"name": "Mike", "role": "user"}] |
| 2 | football | [{"name": "Foo", "role": "user"}, {"name": "Bar", "role": "user"}] |
+----+----------+----------------------------------------------------------------------+
Cập nhật truy vấn:
WITH json_rows AS
(SELECT id, jsonb_array_elements(players) as json_data FROM test_table
WHERE game = 'chess'),
updated_rows AS (
SELECT
id,
array_to_json(array_agg(
CASE WHEN json_data -> 'name' = '"Joe"'
THEN jsonb_set(json_data, '{role}', '"user"')
ELSE json_data END)) as updated_json
FROM json_rows
GROUP BY id
)
UPDATE test_table SET players = u.updated_json
FROM updated_rows u
WHERE test_table.id = u.id;
Kết quả của truy vấn:
+----+----------+---------------------------------------------------------------------+
| id | game | players |
+----+----------+---------------------------------------------------------------------+
| 2 | football | [{"name": "Foo", "role": "user"}, {"name": "Bar", "role": "user"}] |
| 1 | chess | [{"name": "Joe", "role": "user"}, {"name": "Mike", "role": "user"}] |
+----+----------+---------------------------------------------------------------------+
Truy vấn hoạt động theo cách sau:
-
Chuyển đổi mảng json thành các hàng json và lọc chúng bằng
game
tài sản. Điều này được thực hiện bằng cách tạojson_rows
CTE. -
Cập nhật dữ liệu json trong các hàng json nơi người dùng "Joe" được tìm thấy.
-
Khi bạn có các giá trị json mới, chỉ cần cập nhật dựa trên id.
Lưu ý: Như bạn có thể thấy, trong quá trình triển khai hiện tại, mảng json được tạo lại (chỉ trong các hàng cần được cập nhật). Điều này có thể gây ra sự thay đổi thứ tự của các phần tử bên trong mảng.