Вы можете сделать это с помощью комбинации jsonb_each
и jsonb_object_agg
:
CREATE FUNCTION jsonb_replace_by_key(obj jsonb, search text, substitute jsonb) RETURNS jsonb
STRICT LANGUAGE SQL AS $$
SELECT CASE jsonb_typeof(obj)
WHEN 'object' THEN
(SELECT jsonb_object_agg(key, CASE WHEN key = search
THEN substitute
ELSE jsonb_replace_by_key(value, search, substitute)
END)
FROM jsonb_each(obj))
WHEN 'array' THEN
(SELECT jsonb_agg(jsonb_replace_by_key(el, search, substitute))
FROM jsonb_array_elements(obj) el)
ELSE
obj
END;
$$;
Поскольку вы не хотите просто заменять значение свойства, но полностью удалите свойство и добавьте что-нибудь еще, когда оно существовало, вместо этого используйте следующий запрос в object
:
SELECT jsonb_object_agg(key, jsonb_replace_by_key(value, search, substitute))
|| CASE WHEN obj ? search THEN substitute ELSE '{}' END
FROM jsonb_each(obj)
WHERE key <> search
( online demo )