I need to remap the names of properties in the objects of an array in postgres
when performing a SELECT
query.
The table user_phones
has columns id
and phones
. Imagine phones
column type is json
and the array has the following structure:
[
{
model: "samsung s23 utra",
serial_number: 123456
},
{
model: "apple i-phone 15",
serial_number: 123477
}
]
When I perform the select query I want the phones
property in the response to be returned as:
[
{
model: "samsung s23 utra",
serialNumber: 123456
},
{
model: "apple i-phone 15",
serialNumber: 123477
}
]
I was thinking somewhere along the lines of SELECT p.id, json_build_array(SELECT <this is where I'm stuck>) as p.phones FROM user_phones as p
;
I’ve added fiddle here
Is there a simple way of performing this in postgres?
2
Answers
Use the
json_array_elements()
function to expand a JSON array into multiple rows, then applyjson_build_object
to reconstruct the JSON elements, and finally, usejson_agg()
to consolidate these elements back into a JSON array.Results :
Demo here
Cast to
text
,replace()
, cast back tojson
: Demo at db<>fiddle{
"model": "samsung s23 utra",
"serialNumber": "12345"
},
{
"model": "iphone15",
"serialNumber": "12333"
}
]
It’ll target anything matching the pattern regardless of whether that’s actually a key or a value, or a part of either. On the upside, it’s way simpler, faster and frees you from worrying about the current and future structure of objects in your array.
If you deconstruct, rename, reconstruct, you’ll lose keys and values of all elements which structure you didn’t explicitly address, whenever an element has a missing or renamed key, or has some additional data in it.
Another way that’s free from the downsides of blind text replacement is to use
jsonb
operator-
to remove the old key and||
to re-add it with a new name:That way you really only rename the key in each object, without any assumptions about the structure around it. Be warned that switching from
json
tojsonb
will compact insignificant whitespace, as well as order and deduplicate your keys.