Ini harus menjadi informasi yang cukup untuk menyelesaikan kueri:
Mari kita buat data tiruannya
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
}
]
}
]');
Sekarang meledakkan array menggunakan jsonb_array_elements dengan ordinalitas untuk mendapatkan indeks dan properti
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);
Hasil dari query ini adalah:
1,1,1,"{""name"": ""feature1"", ""granted"": false}"
1,1,2,"{""name"": ""feature2"", ""granted"": true}"
Di sana Anda memiliki info yang diperlukan untuk mengambil sub elemen yang Anda butuhkan, serta semua indeks yang Anda butuhkan untuk kueri Anda.
Sekarang, untuk pengeditan terakhir, Anda sudah memiliki kueri yang Anda inginkan:
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}]}';
Di tempat Anda akan menggunakan id, karena itu adalah baris yang Anda minati, dan di indeks Anda mendapatkannya dari kueri. Jadi:
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;
Seperti yang Anda lihat, ini sangat buruk.
Saya akan merekomendasikan menggunakan pendekatan yang lebih sql, yaitu, memiliki fitur dalam tabel alih-alih di dalam json, fk yang menautkannya ke tabel Anda...Jika Anda benar-benar perlu menggunakan json, misalnya, karena domain sangat kompleks dan didefinisikan pada tingkat aplikasi dan sangat fleksibel. Maka saya akan merekomendasikan melakukan pembaruan di dalam kode aplikasi