1

I have a JSONB array below

[
  {
    "name": "test",
    "age": "21",
    "phone": "6589",
    "town": "54"
  },
  {
    "name": "test12",
    "age": "67",
    "phone": "6546",
    "town": "54"
  },
  {
    "name": "test123",
    "age": "21",
    "phone": "6589",
    "town": "54"
  },
  {
    "name": "test125",
    "age": "67",
    "phone": "6546",
    "town": "54"
  }
]

Now I want to delete the object if the name is test or test125. How to delete multiple or single values in JSONB array?

3 Answers 3

1

An update statement including a subquery, which eleminates the unwanted elements with NOT IN operator and aggregates the rest by using jsonb_agg() function, would find out this operation :

Choose this :

 1. UPDATE tab
       SET jsdata = t.js_new
      FROM 
          (
           SELECT jsonb_agg( (jsdata ->> ( idx-1 )::int)::jsonb ) AS js_new
             FROM tab
            CROSS JOIN jsonb_array_elements(jsdata)
             WITH ORDINALITY arr(j,idx)
            WHERE j->>'name' NOT IN ('test','test125') 
          ) t

or this one :

 2. WITH t AS (  
               SELECT jsonb_agg( (jsdata ->> ( idx-1 )::int)::jsonb ) AS js_new    
                 FROM tab   
                CROSS JOIN jsonb_array_elements(jsdata)   
                 WITH ORDINALITY arr(j,idx)   
                WHERE j->>'name' NOT IN ('test','test125')  
               ) 
        UPDATE tab    
           SET jsdata = js_new   
          FROM t

Demo

Sign up to request clarification or add additional context in comments.

1 Comment

tried this solution working for me. Thank you @Barbaros Özhan
1

If you have the Postgres 12, you can use jsonb_path_query_array function to filter the jsonb here is the sample for your question:

with t (j) as ( values ('[
  {"name":"test","age":"21","phone":"6589","town":"54"},
  {"name":"test12","age":"67","phone":"6546","town":"54"}, 
  {"name":"test123","age":"21","phone":"6589","town":"54"},
  {"name":"test125","age":"67","phone":"6546","town":"54"}
]'::jsonb) ) 
select jsonb_path_query_array(j,
  '$[*] ? (@.name != "test" && @.name != "test125")')
from t;

more info on https://www.postgresql.org/docs/12/functions-json.html

Comments

0

I would create a function that does that:

create function remove_array_elements(p_data jsonb, p_key text, p_value text[])
  returns jsonb
as
$$
select jsonb_agg(e order by idx)
from jsonb_array_elements(p_data) with ordinality as t(e,idx)
where t.e ->> p_key <> ALL (p_value) ;
$$
language sql
immutable;

Then you can use it like this:

update the_table
  set the_column = remove_array_elements(the_column, 'name', array['test', 'test125'])
where id = ...;

Online example

4 Comments

function remove_array_elements(jsonb, unknown, integer[]) does not exist Hint: No function matches the given name and argument types. You might need to add explicit type. geting this error
update "calorieTracker" set "caloriesConsumption" = remove_array_elements("caloriesConsumption" , 'c_id', array[21]) where c_id = 40
You are passing an integer array, not a text array.
In remove_array_elements I am passing the_column is my JSON so i am getting this error array ERROR: column "21" does not exist Position: 116

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.