Това трябва да е достатъчно информация, за да завършите заявката:
Нека създадем фиктивните данни
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
}
]
}
]');
Сега разгънете масива с помощта на jsonb_array_elements с ординалност, за да получите индекса и свойството
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);
Резултатът от тази заявка е:
1,1,1,"{""name"": ""feature1"", ""granted"": false}"
1,1,2,"{""name"": ""feature2"", ""granted"": true}"
Там имате необходимата информация, от която се нуждаете, за да извлечете поделементите, от които се нуждаете, както и всички индекси, които са ви необходими за вашата заявка.
Сега, към окончателната редакция, вече имате заявката, която искате:
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}]}';
В къде ще използвате id, защото това са редовете, които ви интересуват, и в индексите, които сте ги получили от заявката. И така:
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;
Както можете да видите, това лесно става много неприятно.
Бих препоръчал или използването на по-sql подход, тоест разполагане на функции в таблица, вместо в json, fk, свързващ това с вашата таблица... Ако наистина трябва да използвате json, например, защото домейнът е наистина сложен и дефиниран на ниво приложение и много гъвкав. Тогава бих препоръчал да правите актуализациите в кода на приложението