Laravel 5では、JSON Where Clausesという便利なものがあります。これは、列に格納されたJSONを格納およびフェッチするMySQLの新しい機能を使用しています。
User::where('meta->colors', 'red')->get()
列colors
のmeta
がred
に設定されるすべての行を返します。
ここで、colors
は文字列ではなく、複数の色(colors => ['red', 'blue', 'green']
)。
colors
に含まれるすべての行を取得する効率的な方法は何ですか?値red
?
JSON_CONTAINS()
はまさにあなたが探しているものをします:
JSON_CONTAINS(target, candidate[, path])
特定の候補JSONドキュメントがターゲットJSONドキュメントに含まれているかどうか、またはパス引数が指定されている場合は、ターゲット内の特定のパスで候補が見つかったかどうかを1または0で返します。 — 12.16.3 JSON値を検索する関数
現在、Laravelのクエリビルダーは対応するAPIを提供していません。ただし open internalsプロポーザル があります。
それまでの間、生のクエリを実行できます。
_\DB::table('users')->whereRaw(
'JSON_CONTAINS(meta->"$.colors", \'["red"]\')'
)->get();
_
これは、_meta->colors
_ JSONフィールドに「赤」を持つすべてのユーザーを返します。 _->
_ operator にはMySQL 5.7.9以降が必要であることに注意してください。
EloquentモデルでwhereRaw()
を直接呼び出すこともできます。
5.6リリースの時点で、Laravelのクエリビルダーには新しい whereJsonContains
メソッドが含まれています。
like
演算子を使用する方法があると思います:
User::where('meta->colors', 'like', '%"red"%')
ただし、値に文字"
が含まれず、区切り文字が変更されない場合にのみ機能します。
この回答の更新、 MySQL または MariaDb によると、正しい構文はJSON_CONTAINS(@json, 'red', '$.colors')
、JSON_EXTRACT
を使用するために必要です。
Say @ Elwin と同様に、
meta
列には次のJSONが含まれている必要があります:{ "colors": ["red", "blue", "green"] }
User::whereRaw("JSON_CONTAINS(JSON_EXTRACT(meta, '$.colors'), '\"{$color}\"')")
値の文では二重引用符を使用することを忘れないでください。JSON_CONTAINS(JSON_EXTRACT(meta, '$.colors'), '"red"')