Как преобразовать массив JSON, вложенный в объект внутри другого массива в Postgres? - PullRequest
0 голосов
/ 01 октября 2018

Я использую Postgres 9.6 и у меня есть поле JSON с именем credits со следующей структурой;Список кредитов, каждый с позицией и несколькими людьми, которые могут быть в этой позиции.

[
  {
    "position": "Set Designers",
    people: [
      "Joe Blow",
      "Tom Thumb"
    ]
  }
]

Мне нужно преобразовать вложенный массив people, который в настоящее время представляет собой просто строки, представляющие их имена, в объекты.с полями name и image_url, например:

[
  {
    "position": "Set Designers",
    people: [
      { "name": "Joe Blow", "image_url": "" },
      { "name": "Tom Thumb", "image_url": "" }
    ]
  }
]

До сих пор мне удавалось найти достойные примеры выполнения этого либо для родительского массива JSON, либо для вложенного поля массивавнутри одного объекта JSON.

Пока это все, чем я мог управлять, и даже это искажает результат.

UPDATE campaigns
  SET credits = (
    SELECT jsonb_build_array(el)
    FROM jsonb_array_elements(credits::jsonb) AS el
  )::jsonb
;

1 Ответ

0 голосов
/ 01 октября 2018

Создайте вспомогательную функцию, чтобы упростить довольно сложную операцию:

create or replace function transform_my_array(arr jsonb)
returns jsonb language sql as $$
    select case when coalesce(arr, '[]') = '[]' then '[]'
    else jsonb_agg(jsonb_build_object('name', value, 'image_url', '')) end
    from jsonb_array_elements(arr)  
$$;

С функцией обновление не так уж и ужасно:

update campaigns
  set credits = (
    select jsonb_agg(jsonb_set(el, '{people}', transform_my_array(el->'people')))
    from jsonb_array_elements(credits::jsonb) as el
  )::jsonb
;

Рабочий пример в rextester.

...