web-dev-qa-db-ja.com

JSON配列に含まれる選択

Laravel 5では、JSON Where Clausesという便利なものがあります。これは、列に格納されたJSONを格納およびフェッチするMySQLの新しい機能を使用しています。

User::where('meta->colors', 'red')->get()

colorsmetaredに設定されるすべての行を返します。

ここで、colorsは文字列ではなく、複数の色(colors => ['red', 'blue', 'green'])。

colorsに含まれるすべての行を取得する効率的な方法は何ですか?値red

11
Elwin

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

5.6リリースの時点で、Laravelのクエリビルダーには新しい whereJsonContains メソッドが含まれています。

16
sepehr

like演算子を使用する方法があると思います:

User::where('meta->colors', 'like', '%"red"%')

ただし、値に文字"が含まれず、区切り文字が変更されない場合にのみ機能します。

2
Elwin

この回答の更新MySQL または MariaDb によると、正しい構文はJSON_CONTAINS(@json, 'red', '$.colors')JSON_EXTRACTを使用するために必要です。

そのため、Laravel(バージョン5.5以下の場合)内のコード。

Say @ Elwin と同様に、meta列には次のJSONが含まれている必要があります:{ "colors": ["red", "blue", "green"] }

User::whereRaw("JSON_CONTAINS(JSON_EXTRACT(meta, '$.colors'), '\"{$color}\"')")

値の文では二重引用符を使用することを忘れないでください。
JSON_CONTAINS(JSON_EXTRACT(meta, '$.colors'), '"red"')

0
alvaro.canepa