Skip to content
Advertisement

Query a column with jsonb data meeting certain criteria

Problem

I have a table like this:

product tags (jsonb)
P001 [{“name”: “LX”,”active”: true}, {“name”: “TX”,”active”: true}]
P002 [{“name”: “LX”,”active”: true}]

I am trying to query against this table to get a list of products with tags that are the same.

I found the following to be insufficient for my query since it will match all products with at least the tag I query for:

SELECT product
FROM product_table 
WHERE tags @> '[
    {"name": "LX","active": true}
]';

Result

product
P001
P002

So I need the match to be more exact without being so strict as to demand order of tag objects in the array. For example:

[
    {
        "name": "LX",
        "active": true
    },
    {
        "name": "TX",
        "active": true
    }
]
-- Interpreted the same as
[
    {
        "name": "TX",
        "active": true
    },
    {
        "name": "LX",
        "active": true
    }
]

Desired Result

A list of products that match only the tags in the query.

Resources

A list of the resources I am using to try and solve the problem.

Advertisement

Answer

Base on the example you give, you can use simultaneous containment in both directions.

...WHERE tags <@ :whatever and tags @> :whatever

If you don’t like repeating the arguments, you could make a custom function, or operator:

create function equal_but_for_order(jsonb,jsonb) returns boolean language sql as $$ 
    select $1 <@ $2 and $1 @> $2
$$;

create operator <@> (function = equal_but_for_order, leftarg = jsonb, rightarg=jsonb);

...WHERE tags <@> :whatever
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement