Reference: JSON Functions
The following functions allow working with embedded json
and jsonb
documents.
create table json_data(data jsonb); -- json behaves similar, but is stored in plain text
insert into json_data
values ('{"id":1, "name": "philipp", "friends": [2, 3]}'),
('{"id":2, "name": "max", "friends": [1]}'),
('{"id":3, "name": "moritz", "friends": [1]}');
Dictionary Access
The ->
operator retrieves the json
element with the specified string key from a JSON dictionary.
When the key is not found, it returns null
.
select data->'name' from json_data;
name
-----------
"philipp"
"max"
"moritz"
(3 rows)
Note the double quotes ("
) around the printed values.
This indicates that the results are JSON strings, not text
columns.
Array Access
The ->
also retrieves the json
element with the specified integer index from a JSON array.
It returns null
for out-of-bounds access.
select data->'friends'->0 from json_data;
0
---
2
1
1
(3 rows)
Text Access
The ->>
operator is similar to ->
, but retrieves text
columns instead of json
columns.
This converts any value, especially JSON strings, but also integers and nested objects, to a text representation.
select data->>'name' from json_data;
name
---------
philipp
max
moritz
(3 rows)
Conversions
Json
and jsonb
columns can be converted to and from text
using standard conversion functions.
select data::text from json_data limit 1;
text
-------------------------------------------------
{"id": 1, "name": "philipp", "friends": [2, 3]}
(1 row)
For jsonb
columns, CedarDB stores semantically equivalent documents, so you might get a syntactically different
text representation in a text::jsonb::text
conversion.
In contrast, json
columns are stored in a plain text representation, where such a conversion is character-by-character
equivalent, but the access operations are slower, since they need to re-parse the JSON string.
Arrays
The json_array_length()
function allows calculating the number of elements in a JSON array:
select json_array_length(data->'friends') from json_data;
json_array_length
-------------------
2
1
1
(3 rows)
JSON arrays can sometimes be hard to work with in SQL, since they are not in a normalized relational model.
To relationalize arrays, you can use the json_array_elements()
function, which transforms a row with a JSON array to
multiple rows with the elements of the array.
This is similar to the unnest()
function for SQL arrays.
For the example, you can get a friends_with
relation from the json array:
select data->'id', json_array_elements(data->'friends')
from json_data;
id | json_array_elements
----+---------------------
1 | 2
1 | 3
3 | 1
2 | 1
(4 rows)