96

For versions less than 9.5 see this question

I have created a table in PostgreSQL using this:

CREATE TEMP TABLE jsontesting
AS
  SELECT id, jsondata::jsonb FROM ( VALUES
    (1, '["abra","value","mango", "apple", "sample"]'),
    (2, '["japan","china","india", "russia", "australia"]'),
    (3, '["must", "match"]'),
    (4, '["abra","value","true", "apple", "sample"]'),
    (5, '["abra","false","mango", "apple", "sample"]'),
    (6, '["string","value","mango", "apple", "sample"]'),
    (7, '["must", "watch"]')
  ) AS t(id,jsondata);

Now what I wanted was to

  • add Something like append_to_json_array takes in the actual jsondata which is a json-array and the newString which I have to add to that jsondata array and this function should return the updated json-array.

    UPDATE jsontesting
    SET jsondata=append_to_json_array(jsondata, 'newString')
    WHERE id = 7;
    
  • remove a value from the json data array, one function for removing the value.

I tried to search documentation of PostgreSQL but found nothing there.

5 Answers 5

182

To add the value use the JSON array append opperator (||)

UPDATE jsontesting
SET jsondata = jsondata || '["newString"]'::jsonb
WHERE id = 7;

Removing the value looks like this

UPDATE jsontesting
SET jsondata = jsondata - 'newString'
WHERE id = 7; 

Concatenating to a nested field looks like this

UPDATE jsontesting
SET jsondata = jsonb_set(
  jsondata::jsonb,
  array['nestedfield'],
  (jsondata->'nestedfield')::jsonb || '["newString"]'::jsonb) 
WHERE id = 7;
Sign up to request clarification or add additional context in comments.

11 Comments

What's the performance like on this for appending to already very large arrays? Does postgres need to load the entirety of the row?
@Rollo anything MVCC. It's how they all work. It solves the isolation problem. When you update a row, that row can not be visible to any transaction prior to your commit, but it must be visible to your own transaction. So you write that row on the table as a dead row. When you commit you make it live. Until you commit, other transactions view the row in it's previous state.
There's a typo. SET jsondata = jsondata - "newString" should be SET jsondata = jsondata - '"newString"'
better yet: SET jsondata = jsondata - 'newString'
Current answer and documentation helped.
|
46

To add to Evan Carroll's answer, you may want to do the following to set the column to an empty array if it is NULL. The append operator (||) does nothing if the column is currently NULL.

UPDATE jsontesting SET jsondata = (
    CASE
        WHEN jsondata IS NULL THEN '[]'::JSONB
        ELSE jsondata
    END
) || '["newString"]'::JSONB WHERE id = 7;

5 Comments

I would either use coalesce, or write it into the conditional.
@EvanCarroll can you add an example please?
@RTW: postgresql etc. has a built in function called coalesce that does the same as this case expression.
@RTW SET jsondata = COALESCE(jsondata, '[]'::JSONB) || '["newString"]'::JSONB
this should be the top answer....I was wondering why it was still null and I suspected this. have an upvote sir.
14

I was facing similar issue to append to an existing json data in postgres with new key-value pair. I was able to fix this using append operator || as follows:

UPDATE jsontesting
SET jsondata = jsondata::jsonb || '{"add_new_data": true}'
WHERE id = 7;

Comments

0

- replace (update) a value from the json data array (replace 'oldString' with 'newString'):

UPDATE jsontesting
SET jsondata = (jsondata || '["newString"]'::jsonb)::jsonb - 'oldString'
WHERE jsondata ? 'oldString'

Comments

-1

remove syntax in MySQL when working with int value in the array

UPDATE jsontesting
SET jsondata= (
    SELECT JSON_ARRAYAGG(value)
    FROM JSON_TABLE(
        jsondata,
        '$[*]' COLUMNS (
            value INT PATH '$'
        )
    ) AS jt
    WHERE value != 7

Comments

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.