6

Given a jsonb field with a value of

{
  values: [null, 'test', { key: 'value' }]
}

is it possible to return an output of

{
  values: [ 'test', { key: 'value' }]
}

Ive looked at the docs and have found some functions like jsonb_strip_nulls() which this only works for keys with null values and array_remove() which I cannot get to work with jsonb.

I would use

UPDATE table 
  SET data = jsonb_set(data, '{values}'::text[], jsonb_agg(elem), false)
FROM data, 
     jsonb_array_elements(data-> 'values') WITH ORDINALITY AS t(elem, nr)
WHERE jsonb_typeof(elem) <> 'null'
GROUP BY (data.id)

and this would work correctly for mose cases, but I need it to work with the case:

{
  values: [null, null, null]
}

the above query does not return

{
  values: []
}

in this case.

Any help is appriciated!! Thanks...

4 Answers 4

8

For PostgreSQL 12:

select jsonb_path_query_array('{"values": [null, "test", { "key": "value" }]}', '$.values[*] ? (@ != null)')    
Sign up to request clarification or add additional context in comments.

Comments

4

With using coalesce you could achieve it like that:

WITH    test( data ) AS (
            VALUES
                ( $${"values": [null, "test", { "key": "value" }]}$$::jsonb ),
                ( $${"values": [null, null, null]}$$::jsonb )
        )
SELECT  jsonb_set(
            d.data,
            '{values}',
            coalesce(
                jsonb_agg(t.elem) FILTER ( WHERE NOT (t.elem = 'null') ),
                $$[]$$::jsonb
            ),
            FALSE
        )
FROM    test d,
        jsonb_array_elements( d.data-> 'values') WITH ORDINALITY AS t(elem)
GROUP BY d.data;


               jsonb_set
----------------------------------------
 {"values": ["test", {"key": "value"}]}
 {"values": []}
(2 rows)

NOTE: I used FILTER instead of WHERE check for null, but with coalesce usage your query should work also.

2 Comments

I know it is a old post, but for those like me still need a solution for this problem, you can use json_strip_nulls available on Postgres 9.5
@EderF.Freitas No, you cannot. Json_strip_nulls was already menationed by the OP, and it only works for keys in objects, not for arrays.
4

This use to be a pain for me as well, so I submitted a patch upstream commited @ 4603903d2 and will be available in PG18.

json{b}_strip_nulls will now accept an additional flag strip_in_arrays to remove null array elements as well.

So you'll be able to do:

 select jsonb_strip_nulls('
{
    "a": 1,
    "b": null,
    "c": [ 5, 6, null, null, 9 ],
    "d": {
        "e": null,
        "f": [ null, null, { "x": null } ]
    }
}
', true );
             jsonb_strip_nulls
--------------------------------------------
 {"a": 1, "c": [5, 6, 9], "d": {"f": [{}]}}
(1 row)

Comments

0

Before PG 18 :

SELECT jsonb_build_array(
    VARIADIC array(SELECT v FROM jsonb_array_elements('[1, 2, null, 3]'::jsonb) v WHERE v != 'null'::jsonb)
);

-- -> [1, 2, 3]

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.