Skip to content

Working with JSON arrays and objects

Anyquery is not strictly normalized. It can handle JSON arrays and objects in columns. Those are stored as text and can be queried using JSON functions. Most plugins return JSON data, so it’s essential to know how to work with them.

Let’s say we have a product table with a column containing an array of tags:

CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT,
tags TEXT
);
idnametags
1Apple[“fruit”, “red”, “sweet”]
2Carrot[“vegetable”, “orange”, “healthy”]

To calculate the number of tags for each product, you can use the json_array_length function:

SELECT name, json_array_length(tags) AS number_of_tags
FROM products;
namenumber_of_tags
Apple3
Carrot3

To explode the tags into separate rows, you can use the json_each virtual table:

SELECT name, value AS tag
FROM products, json_each(tags);
nametag
Applefruit
Applered
Applesweet
Carrotvegetable
Carrotorange
Carrothealthy

From that, you have a normalized view of the tags.

To filter products by a specific tag, you can use the json_has function (from 0.3.2):

SELECT name
FROM products
WHERE json_has(tags, 'fruit');
name
Apple
-- Insert 'juicy' into the tags of all products at the end
SELECT name, json_insert(tags, '$[#]', 'juicy') AS tags
FROM products;
nametags
Apple[“fruit”,“red”,“sweet”,“juicy”]
Carrot[“vegetable”,“orange”,“healthy”,“juicy”]
-- Replace 'red' or 'orange' with 'green' in the tags of all products
SELECT name, json_replace(tags, '$[1]', 'green') AS tags
FROM products;
nametags
Apple[“fruit”,“green”,“sweet”]
Carrot[“vegetable”,“green”,“healthy”]
-- Remove the last tag from the tags of all products
SELECT name, json_remove(tags, '$[#-1]') AS tags
FROM products;
nametags
Apple[“fruit”,“red”]
Carrot[“vegetable”,“orange”]
-- Create an array with 'fruit' and 'green' for all products
SELECT name, json_array('fruit', 'green') AS tags
FROM products;
nametags
Apple[“fruit”,“green”]
Carrot[“fruit”,“green”]

Let’s say we have a product table with a column containing a JSON object:

CREATE TABLE products2 (
id INTEGER PRIMARY KEY,
name TEXT,
properties TEXT
);
idnameproperties
1Apple{“color”: “red”, “taste”: “sweet”, “tags”: [“fruit”, “red”, “sweet”]}
2Carrot{“color”: “orange”, “taste”: “sweet”, “tags”: [“vegetable”, “orange”, “healthy”]}

To extract a field from the JSON object, you can use the json_extract function or its shorthand ->>. You need to provide a JSON path. The object is referenced by $. To access a field, use $.<field>. And for an array, use $[<index>]. To get all elements of an array, use $[*].

SELECT name, properties->>'$.color' AS color
FROM products2;
-- Equivalent to:
SELECT name, json_extract(properties, '$.color') AS color
FROM products2;
namecolor
Applered
Carrotorange

Similarly, you can extract an array from the JSON object:

SELECT name, value AS tag
FROM products2, json_each(properties->'$.tags');
nametag
Applefruit
Applered
Applesweet
Carrotvegetable
Carrotorange
Carrothealthy

To ensure a field exists in the JSON object, you can use the json_has function:

SELECT name, json_has(properties, 'color') AS has_color_field
FROM products2;
namehas_color_field
Apple1
Carrot1
-- Insert or replace a 'price' field with 1.5 for all products
SELECT name, json_set(properties, '$.price', 1.5) AS properties
FROM products2;
nameproperties
Apple{“color”:“red”,“taste”:“sweet”,“tags”:[“fruit”,“red”,“sweet”],“price”:1.5}
Carrot{“color”:“orange”,“taste”:“sweet”,“tags”:[“vegetable”,“orange”,“healthy”],“price”:1.5}
-- Create a new object with 'color' and 'price' for all products
SELECT name, json_object('color', 'brown', 'price', 2.5) AS properties
FROM products2;
nameproperties
Apple{“color”:“brown”,“price”:2.5}
Carrot{“color”:“brown”,“price”:2.5}
-- Filter products by color
SELECT name
FROM products2
WHERE properties->>'$.color' = 'red';
name
Apple
-- Remove the 'color' field from all products
SELECT name, json_remove(properties, '$.color') AS properties
FROM products2;
nameproperties
Apple{“taste”:“sweet”,“tags”:[“fruit”,“red”,“sweet”]}
Carrot{“taste”:“sweet”,“tags”:[“vegetable”,“orange”,“healthy”]}

Congratulations! You now know how to work with JSON arrays and objects in Anyquery (and most SQL databases).