1

I have a table (log_table) and in this table, there is a nested array json field (activities). With using this activities field, I want to insert new field to nested array.

log_table:

- id:long
- activities:json
- date:timestamp

example activities field:

[ 
   { 
      "actionType":"NOTIFICATION",
      "items":null
   },
   { 
      "actionType":"MUTATION",
      "items":[ 
         { 
            "id":387015007,
            "name":"epic",
            "value":{ 
               "currency":"USD",
               "amount":1.76
            }
         },
         { 
            "id":386521039,
            "name":"test",
            "value":{ 
               "currency":"USD",
               "amount":1.76
            }
         }
      ]
   }
]

As query, I've tried:

update 
table_log m 
set activities = 
jsonb_set(
   m.activities::jsonb, 
   array['activities',(pos1-1)::text,'items',(pos-1)::text,'newId'],
   ((obj->>'id'))::jsonb 
)::json
from table_log l
cross join jsonb_array_elements(l.activities::jsonb) with ordinality arr1(elems, pos1)
cross join jsonb_array_elements(case elems->'items' when 'null' then '[null]' else elems->'items' end)  with ordinality arr(obj, pos)
where (obj->>'id')::int = 387015007 and l.id = m.id;

With this query, I got an error like below:

ERROR:  path element at position 1 is not an integer: "activities"

Expected Output:

[ 
   { 
      "actionType":"NOTIFICATION",
      "items":null
   },
   { 
      "actionType":"MUTATION",
      "items":[ 
         { 
            "id":387015007,
            "newId":387015007,
            "name":"epic",
            "value":{ 
               "currency":"USD",
               "amount":1.76
            }
         },
         { 
            "id":386521039,
            "name":"test",
            "value":{ 
               "currency":"USD",
               "amount":1.76
            }
         }
      ]
   }
]

Is there any suggestion?

1 Answer 1

1

Solved it like below:

update 
table_log m 
set activities = 
jsonb_set(
   m.activities::jsonb, 
   array[(pos1-1)::text,'items',(pos-1)::text,'newId'],
   ((obj->>'id'))::jsonb 
)::json
from table_log l
cross join jsonb_array_elements(l.activities::jsonb) with ordinality arr1(elems, pos1)
cross join jsonb_array_elements(case elems->'items' when 'null' then '[null]' else elems->'items' end)  with ordinality arr(obj, pos)
where (obj->>'id')::int = 387015007 and l.id = m.id;

So the problem was;

array['activities',...] -> 'activities' is redundant in here.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.