0

'{"a":1, "b":2, "c":3}'::jsonb ?& array['a', 'b'] checks if right hand side, an array of text, is contained by the top-level keys of the left hand side.

How can I check the opposite? That is, whether the keys of the json string are from a known set of texts.

2 Answers 2

1

You can get the keys of your object with json(b)_object_keys and collect them into an array. Then use the array contains operator:

array(SELECT jsonb_object_keys('{"a":1, "b":2, "c":3}'::jsonb)) <@ array['a', 'b']

Alternatively, you could use a subquery on the keys and conjugate tests against the array (equivalent to the NOT EXISTS check by @GMB):

SELECT bool_and(k = ANY(array['a', 'b'])) FROM jsonb_object_keys(object) as k

(online demo)

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

Comments

0

You can use jsonb_object_keys() and ANY like so:

select 1
from jsonb_object_keys(t.js) o(x)
where not x = ANY(ar)

Here is how to use this in a query:

with t as (
    select '{"a":1, "b":2, "c":3}'::jsonb js, array['a', 'b', 'c'] ar
    union all select '{"a":1, "b":2, "z":3}'::jsonb js, array['a', 'b'] ar
)
select 
    js,
    ar,
    not exists(
        select 1
        from jsonb_object_keys(t.js) o(x)
        where not x = ANY(ar)
    ) res
from t

Yields:

js                       | ar      | res
:----------------------- | :------ | :-----
{"a": 1, "b": 2, "c": 3} | {a,b,c} | true  
{"a": 1, "b": 2, "z": 3} | {a,b}   | false  

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.