Reputation: 1427
how do you escape double quotes and brackets when querying a JSON column containing an array of objects?
This works when I run it...
SELECT boarded, boarded->>"$[0].division.id" AS divisionId FROM onboarder
But this doesn't...
SELECT boarded, boarded->>"$[*].division.id" AS divisionId FROM onboarder
I thought double arrows escaped everything and bought back only the value. This is what I have...
Upvotes: 0
Views: 2868
Reputation: 562270
The ->>
operator does not escape anything. It just converts the result to a scalar data type, like text
or integer
. It's the equivalent of doing JSON_UNQUOTE(JSON_EXTRACT(...)):
Unquotes JSON value and returns the result as a utf8mb4 string.
We can demonstrate the difference between ->
and ->>
by using the result set to create a new table, and inspecting the data types it creates.
create table t as SELECT boarded, boarded->"$[*].division.id" AS divisionId FROM onboarder;
show create table t;
CREATE TABLE `t` (
`boarded` json DEFAULT NULL,
`divisionId` json DEFAULT NULL
);
select * from t;
+------------------------------------+--------------+
| boarded | divisionId |
+------------------------------------+--------------+
| [{"division": {"id": "8ac7a..."}}] | ["8ac7a..."] |
+------------------------------------+--------------+
Note divisionId is a json document, which is an array.
If we use ->>
this is what happens:
create table t as SELECT boarded, boarded->>"$[*].division.id" AS divisionId FROM onboarder;
show create table t;
CREATE TABLE `t` (
`boarded` json DEFAULT NULL,
`divisionId` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin
)
select * from t;
+------------------------------------+--------------+
| boarded | divisionId |
+------------------------------------+--------------+
| [{"division": {"id": "8ac7a..."}}] | ["8ac7a..."] |
+------------------------------------+--------------+
There's no visible difference, because the square brackets are still present. But the latter is stored as a longtext
data type.
Re your comment:
How can I return divisionId as a value so that it's not an array and quoted?
You used $[*]
in your query, and the meaning of this pattern is to return all elements of the array, as an array. To get a single value, you need to query a single element of the array, as in your first example:
boarded->>'$[0].division.id'
This would be so much easier if you didn't use JSON, but stored your data in a traditional table, with one division on its own row, and each field of the division in its own column.
CREATE TABLE divisions (
division_id VARCHAR(...) PRIMARY KEY,
merchant ...
);
CREATE TABLE merchants (
merchant_id ... PRIMARY KEY,
division_id VARCHAR(...),
FOREIGN KEY (division_id) REFERENCES division(division_id)
);
The more examples I see of how developers try to use JSON in MySQL, the more I'm convinced it's a bad idea.
Upvotes: 3