1

My database contains a table which has a column with jsonb type, and I want to update a part of these data using functions/operators from postgreSQL. Given we have this:

{
  "A":[
    {"index":"1"},
    {"index":"2"}
  ],
  "B":[
    {"index":"3"},
    {"index":"4"}
  ]
}

Let's say we went to add a key with an empty array to objects from "A" array, in order to have:

{
  "A":[
    {"index":"1", "myArray":[]},
    {"index":"2", "myArray":[]}
  ],
  "B":[
    {"index":"3"},
    {"index":"4"}
  ]
}

How can I proceed?

I've already tried this kind of things without success:

UPDATE myTable SET myColumn = (myColumn::jsonb)->>'A' || '{"myArray":[]}'

UPDATE myTable SET myColumn = (
  SELECT jsonb_agg(jsonb_set(
    element, 
    array['A'], 
    to_jsonb(((element ->> 'A')::jsonb || '{"myArray":[]}')::jsonb)
  ))
  FROM jsonb_array_elements(myColumn::jsonb) element
)::json

UPDATE myTable SET myColumn = (
  SELECT jsonb_each((element ->> 'A')::jsonb) || '{"myArray":[]}'::jsonb
  FROM jsonb_array_elements(myColumn::jsonb) element
)::json

Obviously, all of these tests have been big failure. I have difficulties to understand how works postgreSQL functions.

Somebody can help?

1 Answer 1

4

The approach with jsonb_array_elements and jsonb_set was the right idea, but somehow you nested them the wrong way round:

UPDATE myTable SET myColumn = jsonb_set(myColumn, '{A}', (
  SELECT jsonb_agg( element || '{"myArray":[]}' )
  FROM jsonb_array_elements(myColumn -> 'A') element
));

(online demo)

Btw if your column already has jsonb data type, you shouldn't need any casts.

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

6 Comments

Thanks a lot, it works! But I added some changes because in fact, my column was json :') so I have included "myColumn" into a to_jsonb() ;)
had to add WHERE jsonb_array_length(myColumn -> 'A') > 0;
@fedor.belov The query was written under the assumption that every json object has an A property that is an array. If that's not the case, yes, you need to add a condition or create the array.
@denyzprahy It's an alias for the relation returned by the jsonb_array_elements function. You can add AS before it to clarify. It ambiguously denotes either the column or the whole single-column relation iirc.
|

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.