Donc, dans Laravel 5, il y a la chose pratique appelée JSON Where Clauses utilisant la nouvelle capacité de MySQL pour stocker et récupérer JSON stocké dans une colonne:
User::where('meta->colors', 'red')->get()
retournerait toutes les lignes, où colors
dans la colonne meta
serait réglé sur red
.
Supposons maintenant que colors
n'est pas une chaîne, mais un tableau contenant plusieurs couleurs (colors => ['red', 'blue', 'green']
).
Quel serait un moyen efficace de récupérer toutes les lignes, où colors
contient par exemple la valeur red
?
JSON_CONTAINS()
fait exactement ce que vous recherchez:
JSON_CONTAINS(target, candidate[, path])
Indique en retournant 1 ou 0 si un document JSON candidat donné est contenu dans un document JSON cible, ou - si un argument de chemin a été fourni - si le candidat se trouve à un chemin spécifique dans la cible. - 12.16.3 Fonctions qui recherchent les valeurs JSON
Actuellement, le générateur de requêtes de Laravel ne fournit pas d'API correspondante. Il y a cependant proposition interne ouverte .
En attendant, vous pouvez exécuter une requête brute:
\DB::table('users')->whereRaw(
'JSON_CONTAINS(meta->"$.colors", \'["red"]\')'
)->get();
Ce qui retournerait tous les utilisateurs qui ont "rouge" dans leur champ JSON meta->colors
. Notez que ->
Opérateur nécessite MySQL 5.7.9+.
Vous pouvez également appeler la whereRaw()
directement sur un modèle Eloquent.
Depuis la version 5.6, le générateur de requêtes de Laravel contient une nouvelle méthode whereJsonContains
.
Je pense qu'une façon serait d'utiliser l'opérateur like
:
User::where('meta->colors', 'like', '%"red"%')
Cependant, cela ne fonctionnerait que si les valeurs ne contiennent jamais le caractère "
et les délimiteurs ne changeraient pas.
Une mise à jour de cette réponse , selon MySQL ou MariaDb , la syntaxe correcte doit être JSON_CONTAINS(@json, 'red', '$.colors')
, et est nécessaire pour utiliser JSON_EXTRACT
.
Comme par exemple @ Elwin , la colonne
meta
doit contenir le JSON suivant:{ "colors": ["red", "blue", "green"] }
User::whereRaw("JSON_CONTAINS(JSON_EXTRACT(meta, '$.colors'), '\"{$color}\"')")
N'oubliez pas d'utiliser des guillemets doubles dans la phrase de valeur.JSON_CONTAINS(JSON_EXTRACT(meta, '$.colors'), '"red"')