Powinno to wystarczyć do uzupełnienia zapytania:
Stwórzmy próbne dane
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
}
]
}
]');
Teraz rozbij tablicę za pomocą jsonb_array_elements z porządkiem, aby uzyskać indeks i właściwość
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);
Wynik tego zapytania to:
1,1,1,"{""name"": ""feature1"", ""granted"": false}"
1,1,2,"{""name"": ""feature2"", ""granted"": true}"
Znajdziesz tam niezbędne informacje, których potrzebujesz, aby pobrać potrzebne elementy podrzędne, a także wszystkie indeksy potrzebne do zapytania.
Teraz, do ostatniej edycji, masz już żądane zapytanie:
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}]}';
W miejscu, w którym użyjesz id, ponieważ są to wiersze, które Cię interesują, aw indeksach uzyskałeś je z zapytania. A więc:
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;
Jak widać, łatwo się to robi bardzo nieprzyjemne.
Polecam albo użycie podejścia bardziej sql, to znaczy posiadanie funkcji w tabeli zamiast wewnątrz json, fk łączącego to z twoją tabelą ... Jeśli naprawdę potrzebujesz użyć json, na przykład, ponieważ domena jest naprawdę złożony i zdefiniowany na poziomie aplikacji oraz bardzo elastyczny. W takim razie polecam wykonanie aktualizacji w kodzie aplikacji