PostgreSQL:按功能将对象添加到jsonb数组

时间:2017-11-01 21:39:08

标签: arrays postgresql function elements jsonb

我有这个jsonb数组: [{"id": 1, "foo": false}, {"id": 1, "foo": true}]

我一直在努力为内部的所有对象添加另一个字段。这是我正在寻找的结果:

[{"id": 1, "foo": false, "bar": true}, {"id": 1, "foo": true, "bar": true}]

我知道我需要编写一个函数,但我对PostgreSQL有点新意,所以我不知道从哪里开始。这是我能找到的最接近的线程:Postgres/JSON - update all array elements但它们是用密钥更新现有对象。

非常感谢任何帮助或指向这个方向。

编辑:

我尝试修改为此功能

create or replace function add_elements(arr jsonb)
returns jsonb language sql as $$
    select jsonb_agg(jsonb_build_object("bar", true))
    from jsonb_array_elements(arr) e(e)    
$$;

但PostgreSQL抱怨ERROR: column "bar" does not exist

我正在使用Postgres 9.5

1 个答案:

答案 0 :(得分:1)

对来自jsonb_array_elements()的元素使用连接运算符:

with my_table(arr) as (
values
    ('[{"id": 1, "foo": false}, {"id": 1, "foo": true}]'::jsonb)
)

select jsonb_agg(elem || '{"bar": true}'::jsonb)
from my_table,
jsonb_array_elements(arr) elem;

                                  jsonb_agg                                  
-----------------------------------------------------------------------------
 [{"id": 1, "bar": true, "foo": false}, {"id": 1, "bar": true, "foo": true}]
(1 row)

您的功能可能如下所示:

create or replace function add_elements(arr jsonb, val jsonb)
returns jsonb language sql as $$
    select jsonb_agg(elem || val)
    from jsonb_array_elements(arr) elem    
$$;


with my_table(arr) as (
values
    ('[{"id": 1, "foo": false}, {"id": 1, "foo": true}]'::jsonb)
)

select add_elements(arr, '{"bar": true}')
from my_table;

                                add_elements                                 
-----------------------------------------------------------------------------
 [{"id": 1, "bar": true, "foo": false}, {"id": 1, "bar": true, "foo": true}]
(1 row)