PostgreSQL查询可从JSON数组字段中查找和/或删除某些元素

问题描述

我们有一个带有jsonb[]列的表,该表包含JSON个对象的数组,这些对象带有各种键。数据库是Postgresql(v9.6)

----------------------------------------------------
| id | data (jsonb[])                              |
----------------------------------------------------
|  1 | [{a:1,B:2,c:3},{a:4,c:5},{a:6,B:7}]   |
|  2 | [{a:8},{B:9,c:10}]                        |
|  3 | [{a:11}]                                    |
----------------------------------------------------

我们要删除或设置为 B的所有值:

所以,我们想得到

---------------------------------------------------------------
| id | data (jsonb[])                                         |
---------------------------------------------------------------
|  1 | [{a:1,B:null/"",B:null/""}]  |
|  2 | [{a:8},{B:null/"",c:10}]                             |
|  3 | [{a:11}]                                               |
---------------------------------------------------------------

------------------------------------------
| id | data (jsonb[])                    |
------------------------------------------
|  1 | [{a:1,{a:6}]   |
|  2 | [{a:8},{c:10}]                   |
|  3 | [{a:11}]                          |
------------------------------------------

如果没有简单的方法来更新B字段,我们很乐意找到一种方法获取所有具有B的记录:在这种情况下,我们可以加载所有记录并在外部进行处理数据库

到目前为止,我们甚至找不到所有具有B:字段的记录。

任何想法都会很棒,谢谢!

解决方法

您可以通过UNNEST Array-> Subtract Element-> Aggregate方法实现

如果要删除元素,请尝试以下操作:

select 
id,jsonb_agg(y-'B') 
from test cross join lateral unnest(data) x(y)
group by id

DEMO

如果要设置元素NULL的值,请尝试以下操作:

select 
id,jsonb_agg(jsonb_set(y,'{B}','null',false)) 
from test cross join lateral unnest(data) x(y)
group by id

DEMO

根据评论进行编辑:

with cte as (
select 
id,array_agg(y-'B') "data"
from test cross join lateral unnest(data) x(y)
group by id
)

update test t1 set data = t2.data from cte t2 where t1.id=t2.id;

FIDDLE