1

The task is to remove multiple nested keys from jsonb field.

Is there any way to shorten this expression without writing a custom function?

SELECT jsonb '{"a": {"b":1, "c": 2, "d": 3}}' #- '{a,b}' #- '{a,d}';

suppose we need to delete more than 2 keys

2 Answers 2

3

There is no way to shorten the expression. If your goal is to pass to the query a single array of keys to be deleted you can use jsonb_set() with jsonb_each():

with my_table(json_col) as (
values
    (jsonb '{"a": {"b":1, "c": 2, "d": 3}}')
)

select jsonb_set(json_col, '{a}', jsonb_object_agg(key, value))
from my_table
cross join jsonb_each(json_col->'a')
where key <> all('{b, d}')    -- input
group by json_col             -- use PK here if exists

    jsonb_set    
-----------------
 {"a": {"c": 2}}
(1 row)

The solution is obviously more expensive but may be handy when dealing with many keys to be deleted.

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

Comments

2

NVM, figured it out)

For this particular case, we can re-assign property with removed keys (flat):

SELECT jsonb_build_object('a', ('{ "b":1, "c": 2, "d": 3 }' - ARRAY['b','d']));

More general approach:

SELECT json_col || jsonb_build_object('<key>',
    ((json_col->'<key>') - ARRAY['key-1', 'key-2', 'key-n']));

Not very useful for deep paths, but works ok with 1-level nesting.

1 Comment

This works in Postgres 10+ (the operator with an array on the right-hand side was introduced in Postgres 10).

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.