在Postgres中向JSON对象添加元素
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Postgres中向JSON对象添加元素相关的知识,希望对你有一定的参考价值。
我在数据库(postgres 9.2.1)中有一个文本字段,其中包含一个json blob。它看起来与此类似,除了所有在一行上,显然:
{
"keyword": {
"checked": "1",
"label": "Keyword"
},
"agency_name": {
"checked": "0",
"label": "Agency Name"
}
}
我需要向json数组添加一个元素,使它看起来像这样:
{
"keyword": {
"checked": "1",
"label": "Keyword"
},
"something_new": {
"checked": "1",
"label": "Something New"
},
"agency_name": {
"checked": "0",
"label": "Agency Name"
}
}
我并不关心新数组元素的位置。它可以在agency_name之后。在postgres中有一个简单的方法吗?
即使我遇到同样的问题,我也想动态地将新元素附加到jsonb []。
假设column_jsonb [] = [{“name”:“xyz”,“age”:“12”}]
UPDATE table_name
SET column_jsonb[] = array_append(column_jsonb[],'{"name":"abc","age":"22"}');
结果:[{“name”:“xyz”,“age”:“12”},{“name”:“abc”,“age”:“22”}]
如果升级到PG9.5.1,那么你可以使用sql操作||
来合并jsonb,例如
select '{"a":1}'::jsonb || '{"a":2, "b":2}'::jsonb
将返回{"a": 2, "b": 2}
如果你不能升级到pg9.5.1,恕我直言,在你的代码中完成工作将是一个更好的选择。您可以将旧的jsonb字符串解析为映射,然后更新映射,然后转换为字符串并更新db-record。
PostgreSQL还没有太多的JSON支持函数:我所能看到的就像array_to_json
一样,如果有相应的方法将原始JSON转换为数组,那么可以使用它,然后你可以操作添加它转换回JSON之前的其他元素。
可能最好的事情是使用PL语言来操纵JSON。一个显而易见的是PLV8,它在PostgreSQL中提供javascript编程功能。您将在JavaScript中编写一个用户定义的函数,该函数将相应地操作JSON blob:
当然,许多其他PL语言(如Java,Python或Perl)在处理JSON数据方面也同样出色,并且可能更容易在您的系统上安装。如果设置了用户定义的函数,则可以在每个函数中编写这些函数。
使用||
合并jsonb并将值设置为它
例:
起源:
在表a
:
id |信息
1 | {“任何”:“B”}
2 | { “AA”: “CC”}
执行后:
update a set info = info::jsonb || ('{"id":}' || id || '}' )::jsonb
产生:
id |信息
1 | {“任何”:“B”,“在哪里”:1}
2 | { “AA”: “CC”, “ID”:2}
something_else:
- 使用
-
‘key’
删除jsonb中的元素 - 如果两个jsonb具有相同的密钥,则merge将替换origin
版本9.5提供了jsonb_set函数,其create_missing = TRUE。在任何其他情况下,使用以下hack来附加信息:
SELECT (trim( trailing '}' from data::text) || ', "c":2}')::json
使用更正确的方式添加/替换新值:
UPDATE t
SET data=t3.data
FROM t AS t1
INNER JOIN
(
SELECT id, json_object_agg(t.k,t.v)
FROM
(
SELECT *
FROM (SELECT id, json_object_keys(data) as k, data->json_object_keys(data) as v FROM t) as t2
WHERE t.k != 'c'
UNION ALL
SELECT id, 'c'::text as k, '"new value"'::json as v FROM t1
) as t3
GROUP by id
) as t4 ON (t1.id=t4.id)
要删除密钥:
UPDATE t
SET data=t3.data
FROM t AS t1
INNER JOIN
(
SELECT id, json_object_agg(t.k,t.v)
FROM (SELECT id, json_object_keys(data) as k, data->json_object_keys(data) as v FROM t) as t2
WHERE t.k != 'c'
GROUP by id
) as t4 ON (t1.id=t4.id)
我有这个问题。这个解决方案是相当“纯粹”的对象操作,我更喜欢'sql'函数到plpgsql。主要的是使用json_each分解 - 给你一条记录 - 然后从中创建一条记录
CREATE OR REPLACE FUNCTION json_extend_object(
input_object json,
append_key text,
append_object json)
RETURNS json AS
$BODY$
select json_object_agg (((json_val)::record).key, ((json_val)::record).value)
from (
select json_val
from (select json_each (input_object) as json_val) disaggr
where ((json_val::record).key != append_key)
union
select newvals
from (
select append_key, append_object
) newvals
) to_rows;
$BODY$
LANGUAGE sql IMMUTABLE
;
以上是关于在Postgres中向JSON对象添加元素的主要内容,如果未能解决你的问题,请参考以下文章
更改(映射)JSON列表形状 - 在TypeScript中向对象添加标记