Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

I have created a table in postgreSQL using this:

create table jsontesting (
  id INTEGER,
  jsondata JSONB
);

and added some rows to it:

INSERT into jsontesting VALUES (1, '["abra","value","mango", "apple", "sample"]'::jsonb);
INSERT into jsontesting VALUES (2, '["japan","china","india", "russia", "australia"]'::jsonb);
INSERT into jsontesting VALUES (3, '["must", "match"]'::jsonb);
INSERT into jsontesting VALUES (4, '["abra","value","true", "apple", "sample"]'::jsonb);
INSERT into jsontesting VALUES (5, '["abra","false","mango", "apple", "sample"]'::jsonb);
INSERT into jsontesting VALUES (6, '["string","value","mango", "apple", "sample"]'::jsonb);
INSERT into jsontesting VALUES (7, '["must", "watch"]'::jsonb);

now what I wanted was to add or remove a value from the json data array.something like update jsontesting set jsondata=append_to_json_array(jsondata, 'newString') WHERE id = 7; where the function append_to_json_array takes in the actual jsondata which is a json-array and the newString which I have to add to that jsondata array and this function should return the updated json-array.Similarly one function for removing the value. I tried to search documentation of postgreSQL but found nothing there.

I used a json because I wanted to store an array of keys for a particular id(user). These keys are provided by user thus they can add/remove values. I dont wanted to create mutiple rows for this. so I created a json array.

share|improve this question
    
"I dont wanted to create mutiple rows for this" - why not? That seems to be the natural way of doing this, normalizing your data. Just because Postgres offers NoSQL/non-relational data types doesn't mean they have to be used for everything. I don't see anything in you example that would require de-normalizing this list of values into one JSON document. – a_horse_with_no_name Jun 8 '15 at 11:26

To add:

update jsontesting 
set jsondata = array_to_json(array(select * from jsonb_array_elements_text(jsondata)) || 'newString'::text)::jsonb 
where id = 7;

To remove:

update jsontesting 
set jsondata = array_to_json(array_remove(array(select * from jsonb_array_elements_text(jsondata)), 'toRemove'))::jsonb 
where id = 7;
share|improve this answer
    
'newString'::text - this probably should be cast. – klin Jun 8 '15 at 20:30
    
@klin fixed, thanks! – Radek Postołowicz Jun 9 '15 at 9:50

Radek's idea can be used to define these handy functions:

create function jsonb_array_append(j jsonb, e text)
returns jsonb language sql immutable
as $$
    select array_to_json(array_append(array(select * from jsonb_array_elements_text(j)), e))::jsonb 
$$;

create function jsonb_array_remove(j jsonb, e text)
returns jsonb language sql immutable
as $$
    select array_to_json(array_remove(array(select * from jsonb_array_elements_text(j)), e))::jsonb 
$$;

create function jsonb_array_replace(j jsonb, e1 text, e2 text)
returns jsonb language sql immutable
as $$
    select array_to_json(array_replace(array(select * from jsonb_array_elements_text(j)), e1, e2))::jsonb 
$$;

The functions in action:

select jsonb_array_append('["alfa", "beta", "gamma"]', 'delta');
         jsonb_array_append
------------------------------------
 ["alfa", "beta", "gamma", "delta"]

select jsonb_array_remove('["alfa", "beta", "gamma"]', 'beta');
 jsonb_array_remove
-------------------
 ["alfa", "gamma"]

select jsonb_array_replace('["alfa", "beta", "gamma"]', 'alfa', 'delta');
     jsonb_array_replace
----------------------------
 ["delta", "beta", "gamma"]

If they prove useful for you, please appreciate Radek's answer. However, I have to add I fully agree with a_horse's comment.

share|improve this answer
    
Maybe it's worth to follow pg convention and prefix your functions with jsonb as they're using jsonb data type. – Radek Postołowicz Jun 9 '15 at 9:53
    
@Radek: You're right, lack of consistency. – klin Jun 9 '15 at 12:02

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.