postgres как добавить ключ к dicts в массиве jsonb - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть массив dicts в столбце jsonb. Я должен обновить и добавить ключ ко всем dicts в этом массиве. Можно ли это сделать в одном операторе обновления?

Столбец Jsonb:

select '[{"a":"val1"}, {"b":"val2"}, {"c":"val3"}]'::jsonb;

Как мне обновить его до:

[
    {
        "a": "val1",
        "x": "xval1"
    },
    {
        "b": "val2",
        "x": "xval2"
    },
    {
        "c": "val3",
        "x": "xval3"
    }
]

Ответы [ 2 ]

0 голосов
/ 01 мая 2020

Предполагая, что у ваших диктов один и только один ключ:

update your_table set
  jsonb_col = (
    select jsonb_agg(
      v || jsonb_build_object(
        'x',
        'x' || (v->>(select min(x) from jsonb_object_keys(v) as x))))
    from jsonb_array_elements(jsonb_col) as v);
0 голосов
/ 01 мая 2020

Во-первых, функция jsonb_array_elements_text() может использоваться для удаления элементов данных jsonb, а затем regexp_replace() может применяться для получения новых jsonb объектов с общими ключами ("x") в подзапросе.

На следующем шаге функция replace() вместе с jsonb_agg() даст желаемый результат, как в следующем запросе:

select id,
       jsonb_agg(
                 (replace(jj.value,'}',',')||replace(jsonb_set(value2::jsonb, '{x}',
                 ('"x'||(jj.value2::jsonb->>'x')::text||'"')::jsonb)::text,'{',''))::jsonb
       ) 
    as result
  from
  (
   select t.id, j.value, regexp_replace(j.value,'[[:alpha:]]+','x') as value2
     from t
    cross join jsonb_array_elements_text(jsdata) j
  ) jj
 group by id;

Демонстрация

Действительно, достаточно использовать шаблон '[[:alpha:]]' для regexp_replace, знак плюс добавляется для случаев, когда данные будут иметь ключевые значения с более чем одной буквой. .

...