更新 jsonb 列中对象数组内对象的键
Update key of object inside array of objects in jsonb column
我有一个名为 data
的 jsonb
列。它嵌套很深,有一个键,它的值是一个对象数组:
select data#>>'{foo,bar,baz,qux}' from my_table limit 1;
-------------
?column? | [{"a": 1, "b:": 2}, {"a": 3, "b": 4}, {"a": 5, "b_": 6}]
如您所见,"b"
键有不同的形式。
我的目标是使用 "b:"
和 "b_"
键更新所有行并将它们设置为 "b"
。
描述了重命名 json 对象的属性的方法。您可以根据这个想法创建一个函数:
create or replace function jsonb_rename_attribute(obj jsonb, old_key text, new_key text)
returns jsonb language sql immutable as $$
select obj - old_key || jsonb_build_object(new_key, obj->old_key)
$$;
和另一个函数来促进 json 数组元素的修改:
create or replace function jsonb_rename_attribute_in_array(arr jsonb, old_key text, new_key text)
returns jsonb language sql immutable as $$
select jsonb_agg(
case when value ? old_key
then jsonb_rename_attribute(value, old_key, new_key)
else value end)
from jsonb_array_elements(arr);
$$;
使用函数更新 table:
update my_table
set data =
jsonb_set(
data,
'{foo,bar,baz,qux}',
jsonb_rename_attribute_in_array(
jsonb_rename_attribute_in_array(
data#>'{foo,bar,baz,qux}',
'b:', 'b'),
'b_', 'b')
)
where jsonb_typeof(data#>'{foo,bar,baz,qux}') = 'array';
插入前的示例触发器:
create or replace function before_insert_on_my_table()
returns trigger language plpgsql as $$
begin
if jsonb_typeof(new.data#>'{foo,bar,baz,qux}') = 'array' then
new.data =
jsonb_set(
new.data,
'{foo,bar,baz,qux}',
jsonb_rename_attribute_in_array(
jsonb_rename_attribute_in_array(
new.data#>'{foo,bar,baz,qux}',
'b:', 'b'),
'b_', 'b')
);
end if;
return new;
end $$;
create trigger before_insert_on_my_table
before insert on my_table
for each row execute procedure before_insert_on_my_table();
我有一个名为 data
的 jsonb
列。它嵌套很深,有一个键,它的值是一个对象数组:
select data#>>'{foo,bar,baz,qux}' from my_table limit 1;
-------------
?column? | [{"a": 1, "b:": 2}, {"a": 3, "b": 4}, {"a": 5, "b_": 6}]
如您所见,"b"
键有不同的形式。
我的目标是使用 "b:"
和 "b_"
键更新所有行并将它们设置为 "b"
。
create or replace function jsonb_rename_attribute(obj jsonb, old_key text, new_key text)
returns jsonb language sql immutable as $$
select obj - old_key || jsonb_build_object(new_key, obj->old_key)
$$;
和另一个函数来促进 json 数组元素的修改:
create or replace function jsonb_rename_attribute_in_array(arr jsonb, old_key text, new_key text)
returns jsonb language sql immutable as $$
select jsonb_agg(
case when value ? old_key
then jsonb_rename_attribute(value, old_key, new_key)
else value end)
from jsonb_array_elements(arr);
$$;
使用函数更新 table:
update my_table
set data =
jsonb_set(
data,
'{foo,bar,baz,qux}',
jsonb_rename_attribute_in_array(
jsonb_rename_attribute_in_array(
data#>'{foo,bar,baz,qux}',
'b:', 'b'),
'b_', 'b')
)
where jsonb_typeof(data#>'{foo,bar,baz,qux}') = 'array';
插入前的示例触发器:
create or replace function before_insert_on_my_table()
returns trigger language plpgsql as $$
begin
if jsonb_typeof(new.data#>'{foo,bar,baz,qux}') = 'array' then
new.data =
jsonb_set(
new.data,
'{foo,bar,baz,qux}',
jsonb_rename_attribute_in_array(
jsonb_rename_attribute_in_array(
new.data#>'{foo,bar,baz,qux}',
'b:', 'b'),
'b_', 'b')
);
end if;
return new;
end $$;
create trigger before_insert_on_my_table
before insert on my_table
for each row execute procedure before_insert_on_my_table();