What's the difference between the PostgreSQL @? and @@ JSONB Operators?

2 min read 05-10-2024
What's the difference between the PostgreSQL @? and @@ JSONB Operators?


PostgreSQL JSONB: @? vs. @@ – Deciphering the Difference

PostgreSQL's JSONB data type is a powerful tool for storing and querying structured data. Two operators, @? and @@, are often used to work with JSONB objects, but their differences can lead to confusion. This article aims to shed light on these operators, explaining how they function and when to use each one.

The Scenario

Imagine you have a table named products with a details column of type JSONB. This column stores product information in a JSON format. Let's say you want to find all products where the color field exists within the details JSONB object. You might instinctively use the @? operator, like this:

SELECT * FROM products WHERE details @? '{"color": "red"}';

But you discover that this query doesn't return any results, even though some products have a "color" field. What's going on?

Understanding the Operators

The key lies in understanding the subtle differences between @? and @@:

  • @? (JSONB Contains Path): This operator checks if the given JSONB object contains a specific path. It focuses on the structure of the JSON document rather than the actual values. For example, details @? '{"color": "red"}' would return true if the details JSONB object has a nested object with a key named "color", regardless of its value.

  • @@ (JSONB Contains Value): This operator checks if the given JSONB object contains a specific value. It focuses on the content of the JSON document and ignores its structure. For example, details @@ 'red' would return true if the details JSONB object contains the value "red" anywhere within its structure.

Why Your Query Failed

In the scenario above, the @? operator was used incorrectly. The query was looking for an exact match of {"color": "red"} within the details JSONB object, which might not exist. Instead, you should have used @@ to check for the presence of the value "red" within the details JSONB object:

SELECT * FROM products WHERE details @@ 'red';

Real-World Examples

Here are a few more examples to illustrate the usage of @? and @@:

Example 1: Finding products with a "color" field:

SELECT * FROM products WHERE details @? '{"color": "red"}'; // Checks for the existence of a "color" field

Example 2: Finding products with a "color" field set to "red":

SELECT * FROM products WHERE details @> '{"color": "red"}'; // Checks for a specific value within the "color" field

Example 3: Finding products with a "size" field greater than "M":

SELECT * FROM products WHERE details @> '{"size": "L"}'; // Checks for a specific value within the "size" field

Example 4: Finding products with a "category" field containing "shoes":

SELECT * FROM products WHERE details @@ 'shoes'; // Checks for the presence of the value "shoes" within the JSONB object

Conclusion

Choosing the right operator for your JSONB queries depends on the specific need. Remember:

  • @? checks for the existence of a path within the JSONB object.
  • @@ checks for the presence of a value within the JSONB object.

By understanding the differences between @? and @@, you can write more efficient and accurate SQL queries to extract valuable information from your JSONB data.