Vous voulez essentiellement appliquer sélection et projection aux éléments de tableau et aux champs d'objet de votre document JSON. Vous devez faire quelque chose comme une clause WHERE pour sélectionner une "ligne" dans le tableau, puis faire quelque chose comme choisir l'un des champs (pas celui que vous avez utilisé dans vos critères de sélection).
Celles-ci sont effectuées en SQL à l'aide de la clause WHERE et de la liste SELECT de colonnes, mais faire la même chose avec JSON n'est pas quelque chose que vous pouvez faire facilement avec des fonctions comme JSON_SEARCH() et JSON_CONTAINS().
La solution fournie par MySQL 8.0 est JSON_TABLE() pour transformer un document JSON en une table dérivée virtuelle, comme si vous aviez défini des lignes et des colonnes conventionnelles. Cela fonctionne si le JSON est au format que vous décrivez, un tableau d'objets.
Voici une démonstration que j'ai faite en insérant vos exemples de données dans un tableau :
create table mytable ( mycol json );
insert into mytable set mycol = '[{"Race": "Orc", "strength": 14}, {"Race": "Knight", "strength": 7}]';
SELECT j.* FROM mytable, JSON_TABLE(mycol,
'$[*]' COLUMNS (
race VARCHAR(10) PATH '$.Race',
strength INT PATH '$.strength'
)
) AS j;
+--------+----------+
| race | strength |
+--------+----------+
| Orc | 14 |
| Knight | 7 |
+--------+----------+
Vous pouvez désormais faire des choses que vous faites normalement avec les requêtes SELECT, comme la sélection et la projection :
SELECT j.strength FROM mytable, JSON_TABLE(mycol, '$[*]'
COLUMNS (
race VARCHAR(10) PATH '$.Race',
strength INT PATH '$.strength'
)
) AS j
WHERE j.race = 'Orc'
+----------+
| strength |
+----------+
| 14 |
+----------+
Cela a quelques problèmes :
-
Vous devez le faire à chaque fois vous interrogez les données JSON, ou bien créez une VIEW pour le faire.
-
Vous avez dit que vous ne connaissiez pas les champs d'attribut, mais pour écrire une requête JSON_TABLE(), vous devez spécifier les attributs que vous souhaitez rechercher et projeter dans votre requête. Vous ne pouvez pas l'utiliser pour des données totalement indéfinies.
J'ai répondu à un certain nombre de questions similaires sur l'utilisation de JSON dans MySQL. J'ai observé que lorsque vous voulez faire ce genre de chose, en traitant un document JSON comme une table afin que vous puissiez appliquer la condition dans la clause WHERE aux champs de vos données JSON, alors toutes vos requêtes deviennent beaucoup plus difficiles. Ensuite, vous commencez à avoir l'impression que vous auriez mieux fait de passer quelques minutes à définir vos attributs afin de pouvoir écrire des requêtes plus simples.