Tengo una matriz compleja que se parece a la siguiente en una columna de la tabla:

{
"sometag": {},
"where": [
    {
        "id": "Krishna",
        "nick": "KK",
        "values": [
            "0"
        ],
        "function": "ADD",
        "numValue": [
            "0"
        ]
    },
    {
        "id": "Krishna1",
        "nick": "KK1",
        "values": [
            "0"
        ],
        "function": "SUB",
        "numValue": [
            "0"
        ]
    }
],
"anotherTag": [],
"TagTag": {
    "tt": "tttttt",
    "tt1": "tttttt"
}

En esta matriz, quiero actualizar la función y numValue de id: "Krishna".

Por favor, ayúdeme.

-1
krishna 22 ene. 2021 a las 09:33

1 respuesta

La mejor respuesta

Esto es realmente desagradable porque

  1. La actualización de un elemento dentro de una matriz JSON siempre requiere expandir la matriz
  2. Arriba: la matriz está anidada
  3. El identificador de los elementos a actualizar es un hermano, no un padre, lo que significa que debe filtrar por un hermano

Así que se me ocurrió una solución, pero quiero negarme: ¡debe evitar hacer esto como una acción regular de la base de datos! Mejor sería:

  1. Analizar su JSON en el backend y realizar las operaciones en su código de backend
  2. Normalice el JSON en su base de datos si esa fuera una tarea común, es decir: cree tablas con las columnas apropiadas y extraiga su JSON en la estructura de la tabla. ¡No almacene objetos JSON completos en la base de datos! ¡Eso haría que cada tarea sea mucho más fácil e increíblemente más eficiente!

demostración: db <> fiddle

SELECT
    jsonb_set(                                                                                -- 5
        (SELECT mydata::jsonb FROM mytable), 
        '{where}', 
        updated_array
    )::json
FROM (
    SELECT
        jsonb_agg(                                                                            -- 4
            CASE WHEN array_elem ->> 'id' = 'Krishna' THEN
                jsonb_set(                                                                    -- 3
                    jsonb_set(array_elem.value::jsonb, '{function}', '"ADDITION"'::jsonb),    -- 2
                    '{numValue}', 
                    '["0","1"]'::jsonb
                )
            ELSE array_elem::jsonb END
        ) as updated_array
    FROM mytable,
        json_array_elements(mydata -> 'where') array_elem                                     -- 1
) s
  1. Extraiga los elementos de la matriz anidada en un elemento por fila
  2. Reemplazar el valor function. Tenga en cuenta los elencos del tipo json al tipo jsonb. Eso es necesario porque no hay función json_set() sino solo jsonb_set(). Naturalmente, si solo tiene el tipo jsonb, las conversiones no son necesarias.
  3. Reemplazar el valor numValue
  4. Reagregar la matriz
  5. Reemplace el valor where del objeto JSON original con el objeto de matriz recién creado.
1
S-Man 22 ene. 2021 a las 07:14