I'm trying to write a function that updates a json
(not jsonb
) field (called settings
) in a table (called user
).
My json object looks like this (however it might not have some of the keys on any nesting level):
{
"audiences": ["val1", "val2"],
"inviteNumber": "123",
"workExperience": [
{
"company": {
"name": "Ace",
"industry": "Accounting",
"revenues": "1M-10M",
"size": "1-10"
},
"title": "Product",
"startDate": {
"month": 1,
"year": 2018
}
}
],
"notifications": {
"emailNotifications": true
},
"jobFunction": "Research & Development",
"phoneNumber": "2134447777",
"areasOfInterest": {
"Recruiting and Staffing": true
}
}
I need to be able to update the "title" and "name" fields of the 0th element inside "workExperience" array.
What I currently have is this:
create or replace function my_function()
returns trigger language plpgsql as $$
declare
companyName character varying(255);
begin
select company.name into companyName from company where id = new.companyid;
update "user" set
email = new.email,
"settings" = jsonb_set(
"settings"::jsonb,
'{workExperience,0}'::TEXT[],
format(
'{"company": {"name": %s}, "title": %s}',
'"' || companyName || '"', '"' || new.title || '"'
)::jsonb
)
where id = new.userid;
return new;
end $$;
However the above implementation rewrites the while workExperience
object removing the keys other than company
and title
.
I've tried looking through this answer on SO, but still wasn't able to implement the updating correctly.
I see that the problem is with how the jsonb_set
works and it does just what I tell it to do: set 0th element of "workExperience" array to the object I define inside format
function.
Seems like I need to use multiple jsonb_set
one inside another, but I can't figure out the way to do it correctly.
How can I update my json field correctly without removing other keys from the object?