2

I seem to be having issues with the @> operator:

CREATE TEMP TABLE test_jsonb (id SERIAL, data jsonb);
INSERT INTO test_jsonb (data) 
VALUES ('[{"role_id": "1", "user_name": "borrey"}]');
CREATE TABLE
INSERT 0 1
SELECT data::text, jsonb_typeof(data), jsonb_array_length(data),
 (data->0)::text,
 data @> (data->0) AS contains_self,
 data @> '{"user_name":"borrey","role_id":"1"}'::jsonb AS contains_manual
FROM test_jsonb;
 
 data | jsonb_typeof | jsonb_array_length | text | contains_self | contains_manual 
-------------------------------------------+--------------+--------------------+-----------------------------------------+---------------+-----------------
 [{"role_id": "1", "user_name": "borrey"}] | array | 1 | {"role_id": "1", "user_name": "borrey"} | f | f
(1 row)

What am I doing wrong?

I would expect contains_self and contains_manual to return t but it is not.

select version();
 version 
---------------------------------------------------------------------------------------------------------------------------
 PostgreSQL 17.4 (Debian 17.4-1.pgdg120+2) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
(1 row)
Bergi
671k162 gold badges1k silver badges1.5k bronze badges
asked May 23, 2025 at 17:15
1

2 Answers 2

4

When using the contains operator with an array, the right hand side of the operator needs to be an array as well. You can try:

data @> jsonb_build_array(data->0)
answered May 23, 2025 at 17:26
Sign up to request clarification or add additional context in comments.

Comments

0

If you are going to do this sort of searching of jsonb data for contained elements it would be a good idea to learn the SQL/JSON Path Language as described here:

https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-SQLJSON-PATH

Then to solve your issue you would use something like:

select 
 jsonb_path_query('[{"role_id": "1", "user_name": "borrey"}]'::jsonb, '$[*]') 
@> 
 '{"role_id": "1", "user_name": "borrey"}'::jsonb;
t

In the above $ represents the item being queried and $[*] fetches the elements in the array, in this case a single object. Then the object is compared to the desired object with @>. For this particular case it a bit of overkill, but if you start digging deeper into jsonb structures it becomes more important.

answered May 24, 2025 at 16:31

3 Comments

I don't think you would ever mix jsonb_path_query with @>. Rather you would just write data @? '$[*] ? (@.role_id == 1 && @.user_name == "borrey")'
Except: select '[{"role_id": "1", "user_name": "borrey"}]'::jsonb @? '$[*] ? (@.role_id == 1 && @.user_name == "borrey")' returns f.
Oh, it's "1" not 1.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.