En mi base de datos de postgres tengo json que se parece a esto:
{ "myArray": [ { "myValue": 1 }, { "myValue": 2 }, { "myValue": 3 } ] } Ahora quiero cambiar el nombre de myValue a otherValue . ¡No puedo estar seguro de la longitud de la matriz! Preferiblemente, me gustaría usar algo como set_jsonb con un comodín como índice de matriz, pero eso no parece ser compatible. Entonces, ¿cuál es la mejor solución?
Tienes que descomponer un objeto jsonb completo, modificar elementos individuales y reconstruir el objeto.
La función personalizada será útil:
create or replace function jsonb_change_keys_in_array(arr jsonb, old_key text, new_key text) returns jsonb language sql as $$ select jsonb_agg(case when value->old_key is null then value else value- old_key || jsonb_build_object(new_key, value->old_key) end) from jsonb_array_elements(arr) $$;Usar:
with my_table (id, data) as ( values(1, '{ "myArray": [ { "myValue": 1 }, { "myValue": 2 }, { "myValue": 3 } ] }'::jsonb) ) select id, jsonb_build_object( 'myArray', jsonb_change_keys_in_array(data->'myArray', 'myValue', 'otherValue') ) from my_table; id | jsonb_build_object ----+------------------------------------------------------------------------ 1 | {"myArray": [{"otherValue": 1}, {"otherValue": 2}, {"otherValue": 3}]} (1 row)El uso de funciones json es definitivamente el más elegante, pero puede arreglárselas usando el reemplazo de caracteres. Transmita el json (b) como texto, realice el reemplazo y luego vuelva a cambiarlo a json (b). En este ejemplo, incluí las comillas y los dos puntos para ayudar a que el texto reemplace el destino de las claves json sin conflicto con los valores.
CREATE TABLE mytable ( id INT, data JSONB ); INSERT INTO mytable VALUES (1, '{"myArray": [{"myValue": 1},{"myValue": 2},{"myValue": 3}]}'); INSERT INTO mytable VALUES (2, '{"myArray": [{"myValue": 4},{"myValue": 5},{"myValue": 6}]}'); SELECT * FROM mytable; UPDATE mytable SET data = REPLACE(data :: TEXT, '"myValue":', '"otherValue":') :: JSONB; SELECT * FROM mytable;