2

I've been trying to update the following :

{"boxes": {"book": 2, "moving": 2}, "goods": {}}

to :

{"boxes": {"book_new": 2, "moving": 2}, "goods": {}}

without using a regular expression or doing this in ruby. but it seems it's a bit tricky. I want to add new key and then delete the old one, I'm not familiar with the syntax and I couldn't find much on the internet.

I was able to add a new element to the data but not to the nested boxes!! like that:

Update moves SET data = data::jsonb || '{"bookasas": 2}'   WHERE data ->> 'boxes' LIKE '%book%';

Any help is appreciated.

3
  • 1
    Possible duplicate of How do I modify fields inside the new PostgreSQL JSON datatype? Commented Aug 29, 2016 at 12:43
  • The question concerns particularly replacing a json key, so it's not a duplicate. Commented Aug 29, 2016 at 12:54
  • @klin The only additional information above the linked question is that in PostgreSQL, there is no direct replace operation: to replace a key-value pair, first the old key needs to be deleted & the new needs to be set. But because OP did figure this out already (I want to add new key and then delete the old one), I think it is already answered. But I agree, this question is in a somewhat gray zone (regarding duplication). Commented Aug 29, 2016 at 15:57

1 Answer 1

5

There is no function to replace json key, so you should delete the old object and add new one:

update moves 
set data = jsonb_set(
    data::jsonb,
    array['boxes'],
    (data->'boxes')::jsonb - 'book' || jsonb_build_object('book_new', data->'boxes'->'book')
    )
where data ->> 'boxes' like '%book%'
returning *;

                         data                         
------------------------------------------------------
 {"boxes": {"moving": 2, "book_new": 2}, "goods": {}}
(1 row)
Sign up to request clarification or add additional context in comments.

9 Comments

I'm getting HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Thanks it works but I had to add ::text to the 'book' and ::jsonb to (data->'boxes')
please update your answer to have these two and it will be perfect, so may other people can benefit from it, many thanks again!
Ok, I've tested it with data of type jsonb.
I'm a bit confused, the solution works well on the data in question.
|

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.