1

I'm using Postgres 9.6 and have a JSON field called credits with the following structure; A list of credits, each with a position and multiple people that can be in that position.

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

I need to transform the nested people array, which are currently just strings representing their names, into objects that have a name and image_url field, like this

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

So far I've only been able to find decent examples of doing this on either the parent JSON array or on an array field nested inside a single JSON object.

So far this is all I've been able to manage and even it is mangling the result.

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

1 Answer 1

3

Create an auxiliary function to simplify the rather complex operation:

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)  
$$;

With the function the update is not so horrible:

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
;

Working example in rextester.

Sign up to request clarification or add additional context in comments.

1 Comment

Using a function is so much more elegant than the multi-nested select aggregations I was attempting.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.