Можете да намерите индекс на търсен елемент с помощта на jsonb_array_elements() with ordinality
(забележка, ordinality
започва от 1, докато първият индекс на json масива е 0):
select
pos- 1 as elem_index
from
samples,
jsonb_array_elements(sample->'result') with ordinality arr(elem, pos)
where
id = 26 and
elem->>'8410' = 'FERR_R';
elem_index
------------
2
(1 row)
Използвайте горната заявка, за да актуализирате елемента въз основа на неговия индекс (обърнете внимание, че вторият аргумент на jsonb_set()
е текстов масив):
update
samples
set
sample =
jsonb_set(
sample,
array['result', elem_index::text, 'ratingtext'],
'"some individual text"'::jsonb,
true)
from (
select
pos- 1 as elem_index
from
samples,
jsonb_array_elements(sample->'result') with ordinality arr(elem, pos)
where
id = 26 and
elem->>'8410' = 'FERR_R'
) sub
where
id = 26;
Резултат:
select id, jsonb_pretty(sample)
from samples;
id | jsonb_pretty
----+--------------------------------------------------
26 | { +
| "result": [ +
| { +
| "8410": "ABNDAT", +
| "8411": "Abnahmedatum" +
| }, +
| { +
| "8410": "ABNZIT", +
| "8411": "Abnahmezeit" +
| }, +
| { +
| "8410": "FERR_R", +
| "8411": "Ferritin", +
| "ratingtext": "Some individual text"+
| } +
| ] +
| }
(1 row)
Последният аргумент в jsonb_set()
трябва да е true
за принудително добавяне на нова стойност, ако неговият ключ все още не съществува. Може обаче да се пропусне, тъй като стойността му по подразбиране е true
.
Въпреки че проблемите с едновременността изглеждат малко вероятни (поради ограничителното условие WHERE и потенциално малък брой засегнати редове), може да се интересувате и от Atomic UPDATE .. SELECT в Postgres.