Toto by mělo stačit k dokončení dotazu:
Pojďme vytvořit simulovaná data
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
}
]
}
]');
Nyní rozložte pole pomocí jsonb_array_elements s ordinalitou, abyste získali index a vlastnost
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);
Výsledek tohoto dotazu je:
1,1,1,"{""name"": ""feature1"", ""granted"": false}"
1,1,2,"{""name"": ""feature2"", ""granted"": true}"
Zde máte potřebné informace, které potřebujete k načtení dílčích prvků, které potřebujete, a také všechny indexy, které jste potřebovali pro svůj dotaz.
Nyní, ke konečné úpravě, jste již měli dotaz, který jste chtěli:
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}]}';
V tom, kde použijete id, protože to jsou řádky, které vás zajímají, a v indexech, které jste získali z dotazu. Takže:
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 můžete vidět, je to velmi ošklivé.
Doporučil bych buď použít přístup více sql, to znamená mít funkce v tabulce místo uvnitř json, fk, který to propojí s vaší tabulkou...Pokud opravdu potřebujete použít json, například protože doména je skutečně komplexní a definovaný na aplikační úrovni a velmi flexibilní. Pak bych doporučil provést aktualizace v kódu aplikace