Tushar Garg
Tushar Garg

Reputation: 35

Postgres: How to alter jsonb value type for each element in an array?

I have a jsonb column named items in Postgres 10.12 like this:

{
    "items": [
        {
            "itemQty": 2,
            "itemName": "snake"
        },
        {
            "itemQty": 1,
            "itemName": "x kodiyum"
        }
    ]
}

Now I want to convert itemQty type to string for every array element so that the new values are like this:

{
    "items": [
        {
            "itemQty": "2",
            "itemName": "snake"
        },
        {
            "itemQty": "1",
            "itemName": "x kodiyum"
        }
    ]
}

How do I do this? I have gone through the documentation for Postgres jsonb and couldn't figure out.

On the server-side, I am using Spring boot and Hibernate with com.vladmihalcea.hibernate.type.json (Hibernate Types 52) if it helps.

Thanks

Upvotes: 1

Views: 137

Answers (1)

GMB
GMB

Reputation: 222582

You could unnest the array, modify the elements, and then rebuild it. Assuming that the primary key of your table is id, that would be:

select jsonb_build_object(
    'items', jsonb_agg(
        jsonb_build_object(
            'itemQty',  (x.obj ->> 'itemQty')::text,
            'itemName', x.obj ->> 'Name'
        )
    ) 
    )new_items
from mytable t
cross join lateral jsonb_array_elements(t.items -> 'items') as x(obj)
group by id

Note that the explicit cast to ::text is not really needed here, as ->> extract text values anyway: I kept it because it makes the intent clearer.

If you want an update statement:

update mytable t
set items = (
    select jsonb_build_object(
        'items', jsonb_agg(
            jsonb_build_object(
                'itemQty',  (x.obj ->> 'itemQty')::text,
                'itemName', x.obj ->> 'Name'
            )
        ) 
    )
    from jsonb_array_elements(t.items -> 'items') as x(obj)
)

Demo on DB Fiddle

Upvotes: 1

Related Questions