N P
N P

Reputation: 2619

Removing element from array within object JSONB

I am attempting to remove an element from my database. The element I want to remove is within a JSON object called playerContainer which contains an array named players. This all sits within a table called site_content. I am trying to remove the object based on it's ID, however I get this error.

DELETE elem from site_content, lateral jsonb_array_elements(content->'playersContainer'->'players') elem where elem @> '{"id":"22"}'
because: ERROR: syntax error at or near "elem" Position: 27

Below is my query, can anyone see where I am going wrong?

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

Here is the sample 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

            },
}

Upvotes: 1

Views: 4230

Answers (1)

Evren Yurtesen
Evren Yurtesen

Reputation: 2349

DELETE works on rows of a table. Therefore you can't use it unless if you want to remove the complete row.

Try this:

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

Now you need to find the position of the player you want to remove, lets say you want Rick with id 2 (minus 1 because index starts from 0)

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

Now you can combine this with an UPDATE statement to update the field. Use minus (-) operator to remove the element at wanted index.

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 );

End result:

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

Upvotes: 4

Related Questions