Đây phải là đủ thông tin để hoàn thành truy vấn:
Hãy tạo dữ liệu giả
create table a (id serial primary key , b jsonb);
insert into a (b)
values ('[
{
"name": "test",
"features": [
{
"name": "feature1",
"granted": false
},
{
"name": "feature2",
"granted": true
}
]
},
{
"name": "another-name",
"features": [
{
"name": "feature1",
"granted": false
},
{
"name": "feature2",
"granted": true
}
]
}
]');
Bây giờ hãy bùng nổ mảng bằng cách sử dụng jsonb_array_elements với thứ tự để lấy chỉ mục và thuộc tính
select first_level.id, position, feature_position, feature
from (select a.id, arr.*
from a,
jsonb_array_elements(a.b) with ordinality arr (elem, position)
where elem ->> 'name' = 'test') first_level,
jsonb_array_elements(first_level.elem -> 'features') with ordinality features (feature, feature_position);
Kết quả của truy vấn này là:
1,1,1,"{""name"": ""feature1"", ""granted"": false}"
1,1,2,"{""name"": ""feature2"", ""granted"": true}"
Ở đó, bạn có thông tin cần thiết để tìm nạp các phần tử phụ mà bạn cần, cũng như tất cả các chỉ mục mà bạn cần cho truy vấn của mình.
Bây giờ, đến lần chỉnh sửa cuối cùng, bạn đã có truy vấn mà bạn muốn:
UPDATE my_table SET modules =
jsonb_insert(my_column, '{0, features, 0}', '{"name": "newFeature", "granted": false}')
WHERE my_column ->> 'name' = 'test' AND my_column @> '{"features": [{"name":"feature1", "granted": false}]}';
Tại nơi bạn sẽ sử dụng id, vì đó là những hàng mà bạn quan tâm và trong các chỉ mục bạn lấy chúng từ truy vấn. Vì vậy:
UPDATE my_table SET modules =
jsonb_insert(my_column, '{' || exploded_info.position::string || ', features, ' || exploded_info.feature_position || '}', '{"name": "newFeature", "granted": false}') from (/* previous query */) as exploded_info
WHERE exploded_info.id = my_table.id and exploded_info.feature -> 'granted' = false;
Như bạn có thể thấy, điều này rất khó chịu.
Tôi khuyên bạn nên sử dụng một cách tiếp cận sql hơn, nghĩa là có các tính năng trong một bảng thay vì bên trong một json, một liên kết fk với bảng của bạn ... Nếu bạn thực sự cần sử dụng json, chẳng hạn như vì tên miền thực sự phức tạp và được xác định ở cấp độ ứng dụng và rất linh hoạt. Sau đó, tôi khuyên bạn nên thực hiện cập nhật bên trong mã ứng dụng