Postgresql - json 更新数组中对象的键
Postgresql - json update key of object in array
我的数据库中有以下 json:
[
{"schedule_id":1,"datetime":"2017-05-12 00:00:00","status":"available"},
{"schedule_id":2,"datetime":"2017-05-12 02:00:00","status":"available"}
]
我想更新 schedule_id = 2
.
对象的 status
属性
我找到了类似的东西,但这需要数组中对象的索引:
select
jsonb_set('[
{"schedule_id":1,"datetime":"2017-05-12 00:00:00","status":"available"},
{"schedule_id":2,"datetime":"2017-05-12 02:00:00","status":"available"}
]',
'{1, status}',
'"booked"')
`
您可以使用 jsonb_array_elements()
取消嵌套数组,修改过滤后的元素,最后使用 jsonb_agg().
将结果聚合到 json 数组中 使用简单的连接运算符替换内部 json 对象。
示例(jsonb_pretty()
不需要,用于良好的输出):
with my_table(data) as (
values(
'[
{"schedule_id":1,"datetime":"2017-05-12 00:00:00","status":"available"},
{"schedule_id":2,"datetime":"2017-05-12 02:00:00","status":"available"}
]'::jsonb)
)
select
jsonb_pretty(jsonb_agg(
case value->>'schedule_id'
when '2' then value || '{"status":"booked"}'
else value
end
))
from my_table,
jsonb_array_elements(data);
jsonb_pretty
--------------------------------------------
[ +
{ +
"status": "available", +
"datetime": "2017-05-12 00:00:00",+
"schedule_id": 1 +
}, +
{ +
"status": "booked", +
"datetime": "2017-05-12 02:00:00",+
"schedule_id": 2 +
} +
]
(1 row)
使用此更新 table 的最简单方法是将查询包含在自定义函数中,例如:
create or replace function change_schedule_status(schedule jsonb, id int, status text)
returns jsonb language sql as $$
select
jsonb_agg(
case value->>'schedule_id'
when id::text then value || jsonb_build_object('status', status)
else value
end
)
from jsonb_array_elements(schedule);
$$;
update search
set schedule = change_schedule_status(schedule, 2, 'booked')
where id = 1 -- probably the table has a primary key?
returning *;
我的数据库中有以下 json:
[
{"schedule_id":1,"datetime":"2017-05-12 00:00:00","status":"available"},
{"schedule_id":2,"datetime":"2017-05-12 02:00:00","status":"available"}
]
我想更新 schedule_id = 2
.
status
属性
我找到了类似的东西,但这需要数组中对象的索引:
select
jsonb_set('[
{"schedule_id":1,"datetime":"2017-05-12 00:00:00","status":"available"},
{"schedule_id":2,"datetime":"2017-05-12 02:00:00","status":"available"}
]',
'{1, status}',
'"booked"')
`
您可以使用 jsonb_array_elements()
取消嵌套数组,修改过滤后的元素,最后使用 jsonb_agg().
将结果聚合到 json 数组中 使用简单的连接运算符替换内部 json 对象。
示例(jsonb_pretty()
不需要,用于良好的输出):
with my_table(data) as (
values(
'[
{"schedule_id":1,"datetime":"2017-05-12 00:00:00","status":"available"},
{"schedule_id":2,"datetime":"2017-05-12 02:00:00","status":"available"}
]'::jsonb)
)
select
jsonb_pretty(jsonb_agg(
case value->>'schedule_id'
when '2' then value || '{"status":"booked"}'
else value
end
))
from my_table,
jsonb_array_elements(data);
jsonb_pretty
--------------------------------------------
[ +
{ +
"status": "available", +
"datetime": "2017-05-12 00:00:00",+
"schedule_id": 1 +
}, +
{ +
"status": "booked", +
"datetime": "2017-05-12 02:00:00",+
"schedule_id": 2 +
} +
]
(1 row)
使用此更新 table 的最简单方法是将查询包含在自定义函数中,例如:
create or replace function change_schedule_status(schedule jsonb, id int, status text)
returns jsonb language sql as $$
select
jsonb_agg(
case value->>'schedule_id'
when id::text then value || jsonb_build_object('status', status)
else value
end
)
from jsonb_array_elements(schedule);
$$;
update search
set schedule = change_schedule_status(schedule, 2, 'booked')
where id = 1 -- probably the table has a primary key?
returning *;