从对象 JSONB 中的数组中删除元素

Posted

技术标签:

【中文标题】从对象 JSONB 中的数组中删除元素【英文标题】:Removing element from array within object JSONB 【发布时间】:2017-02-17 13:21:50 【问题描述】:

我正在尝试从我的数据库中删除一个元素。我要删除的元素位于一个名为 playerContainer 的 JSON 对象中,该对象包含一个名为 player 的数组。这一切都位于一个名为 site_content 的表中。我正在尝试根据它的 ID 删除对象,但是我收到了这个错误。

删除元素 来自站点内容, 横向 jsonb_array_elements(content->'playersContainer'->'players') elem 其中 elem @> '"id":"22"' 因为:错误:“elem”位置或附近的语法错误:27

下面是我的查询,谁能看出我哪里出错了?

DELETE elem 
from site_content, 
lateral jsonb_array_elements(content->'playersContainer'->'players') elem 
where elem @> '"id":"1"' 

这里是示例 JSON

"playersContainer": 
        "players": [
            
                "id": "1",
                "name": "Nick",
                "teamName": "Shire Soldiers",
                "ratings": [
                    1,
                    5,
                    6,
                    9
                ],
                "assists": 17,
                "manOfTheMatches": 20,
                "cleanSheets": 1,
                "data": [
                    3,
                    2,
                    3,
                    5,
                    6
                ],
                "totalGoals": 19

            ,

【问题讨论】:

提供您的 JSON 数据示例 我已经在上面发布了一些示例 JSON。 请提供表定义(psql 中的\d site_content)。 "footballprototype";"public";"site_content";"id";1;"";"NO";"字符变化";255;1020;;; "footballprototype";"public";"site_content";"content";2;"";"YES";"jsonb";;;;; 我有一个名为 site_content 的表,有 2 行,一个叫做 id,一个叫做 content,上面有 JSON 【参考方案1】:

DELETE 作用于表的行。因此,除非您想删除整个行,否则您不能使用它。

试试这个:

create temp table testing as
select 
    ' "playersContainer": 
        "players": [
            
                "id": "1",
                "name": "Nick"
            ,
            
                "id": "2",
                "name": "Rick"
            ,
            
                "id": "3",
                "name": "Trick"
            
        ]
     '::jsonb as value;

现在您需要找到要移除的玩家的位置,假设您想要 id 为 2 的 Rick(减去 1,因为索引从 0 开始)

select position-1 from testing, jsonb_array_elements(value->'playersContainer'->'players') with ordinality arr(elem, position) WHERE elem->>'id' = '2';

现在您可以将其与UPDATE 语句结合使用来更新字段。使用减号 (-) 运算符删除所需索引处的元素。

UPDATE testing SET value = jsonb_set(value, 'playersContainer,players', (value->'playersContainer'->'players') - (select position-1 from testing, jsonb_array_elements(value->'playersContainer'->'players') with ordinality arr(elem, position) WHERE elem->>'id' = '2')::int );

最终结果:


    "playersContainer":
        "players":[
            
                "id":"1",
                "name":"Nick"
            ,
            
                "id":"3",
                "name":"Trick"
            
        ]
    

【讨论】:

如果找不到元素,这对我来说会失败(它将删除“玩家”中的所有元素)......有什么想法吗? 把它分成2个查询。仅当在上一个查询中找到位置时才执行 UPDATE? ——是的,这就是我最终做的事情

以上是关于从对象 JSONB 中的数组中删除元素的主要内容,如果未能解决你的问题,请参考以下文章

从 jsonb 数组中删除元素

从 jsonb 数组包含具有特定属性的元素的表中选择

Postgresql Jsonb字段内含数组属性的删除元素操作

从 postgres 表中提取 json 数组给出错误:无法从标量中提取元素

PostgreSQL jsonb-通过数组元素搜索字符串

java中怎么删除数组中的元素?