简体   繁体   中英

Add new fields to nested JSON array in JSONB

I have a nested JSON structure stored in a PostgreSQL table.

Table users :

id | content [JSON]

JSON:

{
  "purchases": [
    {
      "id": 1,
      "costs": [
        {
          "amount": 23
        },
        {
          "amount": 34
        }
      ]
    },
    {
      "id": 2,
      "costs": [
        {
          "amount": 42
        }
      ]
    }
  ]
}

I would like to add a field "jsonClass": "Static" to all the objects within the costs array so I have following in the end:

{
  "purchases": [
    {
      "id": 1,
      "costs": [
        {
          "jsonClass": "Static",
          "amount": 23
        },
        {
          "jsonClass": "Static",
          "amount": 34
        }
      ]
    },
    {
      "id": 2,
      "costs": [
        {
          "jsonClass": "Static",
          "amount": 42
        }
      ]
    }
  ]
}

I couldn't figure out how to add values to such a nested structure. Anyone knows how to achieve such thing? The only way I found was to make it a text and do string replace which is not very performant and I have a lot of such entries.

Unfortunately, due to having to change multiple sub-objects, I don't know of a better way than to deconstruct and then reconstruct the object. It gets pretty hairy.

UPDATE users
SET content=(
  SELECT jsonb_agg(purchase)
  FROM (
    SELECT jsonb_build_object('id', pid, 'purchases', jsonb_agg(cost)) AS purchase
    FROM (
      SELECT pid, cost || '{"jsonClass":"static"}'::jsonb AS cost
      FROM (
        SELECT purchase->'id' AS pid, jsonb_array_elements(purchase->'costs') AS cost 
        FROM jsonb_array_elements(content::jsonb->'purchases') AS purchase
      ) AS Q  
    ) AS R
    GROUP BY pid
  ) AS S
);

Fiddle

EDIT: Sorry about all the edits, forgot to test for multiple rows. Should be good now. It might be possible to simplify it a bit more, not sure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM