Professional Documents
Culture Documents
Postgresql Json
Postgresql Json
1
JSON in PostgreSQL
However, if your requirements mean that your data structure needs to be flexible, then a JSON
field may be good for your database.
One example may be where a user can add custom attributes. If it was done using a normalised
database, this may involve altering tables, or creating an Entity Attribute Value design, or some
other method.
If a JSON field was used for this, it would be much easier to add and maintain these custom
attributes.
The JSON data can also be stored in your database and processed by an ORM (Object Relational
Mapper) or your application code, so your database may not need to do any extra work.
2
JSON in PostgreSQL
JSON data can be enclosed in curly brackets which indicate it's an object.
{"username": "jsmith"}
This is the same data as the earlier example, but it's now an object. This means it can be treated as
a single unit by other areas of the application.
How does this help? It's good for when there are multiple attributes:
{
"username": "jsmith",
"location": "United States"
}
Additional attributes, or name/value pairs, can be added by using a comma to separate them.
You'll also notice in this example the curly brackets are on their own lines and the data is indented.
This is optional: it's just done to make it more readable.
Arrays
JSON also supports arrays, which is a collection of records within an object. Arrays in JSON are
included in square brackets and have a name:
{
"username": "jsmith",
"location": "United States",
"posts": [
{
"id":"1",
"title":"Welcome"
},
{
"id":"4",
"title":"What started it all"
}
]
}
In this example, this object has an attribute called "posts". The value of posts is an array, which we
can see by the opening square bracket "[".
3
JSON in PostgreSQL
Inside the square bracket, we have a set of curly brackets, indicating an object, and inside those we
have an id of 1 and a title of Welcome. We have another set of curly brackets indicating another
object.
These two objects are posts and they are contained in an array.
And that covers the basics of what JSON is.
If JSON is new to you, don't worry, it gets easier as you work with it more.
If you're experienced with JSON, you'll find the rest of the guide more useful as we go into the
details of working with JSON in PostgreSQL.
4
JSON in PostgreSQL
Feature JSON JSONB
5
JSON in PostgreSQL
Using the method above, we needed to enter in the data in exactly the right format.
Inserting Arrays
If you want to insert JSON data that contains arrays, you can enter it using text in a JSON format.
Here's how to insert an array by just specifying it in a JSON format.
INSERT INTO product (id, product_name, attributes)
VALUES (2, 'Desk','{"color":"black", "material":"metal",
"drawers":[{"side":"left", "height":"30cm"}, {"side":"left",
"height":"40cm"}]}');
6
JSON in PostgreSQL
This will insert a new product that has an array of drawers. As you can probably see by this
statement, reading it (and writing it) is a bit tricky.
You can insert simpler arrays using this method too.
INSERT INTO product (id, product_name, attributes)
VALUES (3, 'Side Table','{"color":"brown", "material":["metal",
"wood"]}');
The INSERT statements will work.
7
JSON in PostgreSQL
There are several other functions available to help you insert JSON values into a table:
● to_json and to_jsonb
● array_to_json
● row_to_json
● json_build_array and jsonb_build_array
● json_object and jsonb_object
8
JSON in PostgreSQL
1 Chair "brown"
2 Desk "black"
9
JSON in PostgreSQL
Here's our updated query. We'll select both methods so you can see the difference
SELECT
id,
product_name,
attributes -> 'color' AS color_key,
attributes ->> 'color' AS color_value
FROM product;
Here are the results.
id product_name color_key color_value
1 Chair 60cm
2 Desk null
10
JSON in PostgreSQL
Null values are shown where the key does not exist.
1 Chair null
11
JSON in PostgreSQL
This example will get the attributes column, then the drawers element, then the element at
position 1 (which is the 2nd element as arrays start at 0).
Notice how the -> symbol is used, as this symbol retrieves the element and not just the text.
Here's a sample query.
SELECT
id,
product_name,
attributes -> 'drawers' -> 1 AS drawer_value
FROM product;
The results are:
product_nam
id e drawers
1 Chair null
12
JSON in PostgreSQL
13
JSON in PostgreSQL
Often we need to filter on one of the keys or values. How can we do that?
What if we try using the LIKE keyword with a partial match?
SELECT
id,
product_name,
attributes
FROM product
WHERE attributes LIKE '%"color":"brown"%';
ERROR: operator does not exist: jsonb ~~ unknown
LINE 27: WHERE p.attributes LIKE '%"color":"brown"%';
^
HINT: No operator matches the given name and argument type(s). You
might need to add explicit type casts.
We get an error in PostgreSQL as we can't use the LIKE attribute on a JSONB column.
There are several features in PostgreSQL that make it possible to filter on JSON data.
14
JSON in PostgreSQL
We've added this notation to our WHERE clause, and added a condition where the color is equal
to "brown".
Here's what happens when we run the query.
ERROR: invalid input syntax for type json
LINE 27: WHERE attributes -> 'color' = 'brown';
^
DETAIL: Token "brown" is invalid.
CONTEXT: JSON data, line 1: brown
We get this error because the query is expecting a JSON object in the WHERE clause, and we
provided the string of "brown". It's expecting a JSON object because we used ->.
We can use ->> to be able to provide a string.
SELECT
id,
product_name,
attributes
FROM product
WHERE attributes ->> 'color' = 'brown';
The results of this query are shown below.
id product_name attributes
15
JSON in PostgreSQL
PostgreSQL includes some functions that let you expand the JSON fields and display them in
different rows.
The JSONB_EACH function will display each key and value pair as elements. It will split each key
into separate rows.
SELECT
id,
product_name,
JSONB_EACH(attributes)
FROM product;
Here are the results:
id product_name jsonb_each
1 Chair (color,"""brown""")
1 Chair (height,"""60cm""")
1 Chair (material,"""wood""")
2 Desk (color,"""black""")
2 Desk (material,"""metal""")
16
JSON in PostgreSQL
JSONB_OBJECT_KEYS(attributes)
FROM product;
The results are:
id product_name jsonb_object_keys
1 Chair color
1 Chair height
1 Chair material
2 Desk color
2 Desk drawers
2 Desk material
color 4
material 4
drawers 1
17
JSON in PostgreSQL
height 1
18
JSON in PostgreSQL
You can update a JSON field using an UPDATE statement. Using this UPDATE statement, you can
add a new key and value to the field by concatenating it to the existing value.
Here's the syntax:
UPDATE table
SET json_field = json_field || new_json_data;
If we want to add a new key and value pair to one of our products, we can concatenate a JSON
value to the existing value and run it in the UPDATE statement.
Here's our table before the update:
id product_name attributes
19
JSON in PostgreSQL
The JSONB_SET function allows you to update an existing key to a new value. This is helpful if you
don't want to read and update the entire field just to change one value.
The syntax look like this:
JSONB_SET(json_column, key, new_value)
Let's say we want to update the height for our Chair product from 60cm to 75cm.
Here's the table before the update:
id product_name attributes
20
JSON in PostgreSQL
21
JSON in PostgreSQL
Select Performance
For example, let's say we want to select all products where the color is brown. We can use the ->>
operator in the WHERE clause that we saw earlier in this guide:
SELECT
id,
product_name,
attributes
FROM product
WHERE attributes ->> 'color' = 'brown';
22
JSON in PostgreSQL
QUERY PLAN
23
JSON in PostgreSQL
However, we can see the cost is a lot less:
Before Index After Index
cost=0.00..12.40 cost=0.00..1.06
This may result in a faster query. The difference may be more evident on larger tables.
24
JSON in PostgreSQL
Conclusion
I hope you found this guide useful. Have you used JSON fields in PostgreSQL? What has your
experience been like? Do you have any questions? Feel free to use the comments section on the
post.
25