2017-12-29 18 views
1

値の配列を含むJSONフィールドを照会しようとしています。 例として、テーブル「ユーザー」とフィールド「フレンズ」という名前を付けます。ここで友達フィールドがどのように見えるかです:JSON配列を含むJSONフィールドにLaravel 5.4クエリを作成する

[{ 
    "id": 1, 
    "img": "img-1.jpg", 
    "name": "Name 1" 
}, 
{ 
    "id": 2, 
    "img": "img-2.jpg", 
    "name": "Name 2" 
}, 
{ 
    "id": 3, 
    "img": "img-3", 
    "name": "Name 3" 
}] 

だから、私は何をしたいのidは3に等しいがある友達フィールドからユーザ・テーブル・クエリのすべてにです。

{ 
    "id": 1, 
    "img": "img-1.jpg", 
    "name": "Name 1" 
} 

絶望的な、と私はそれが非常にではないことを知っているにもかかわらず:

だから、のようなもの:フィールドには、それだけだったので、もし、配列が含まれていなかった場合はもちろんUser::where('friends->id', 3)->orderBy('id', 'desc')->get(); 、上記exempleは完璧に動作します論理、私は "どこで"試してみました:User::whereIn('friends->id', [3])->get()。または、次のようなもの:User::where('friends->[0]->id', 3)->get()User::where('friends->[*]->id', 3)->get()User::where('friends->*->id', 3)->get()

私もJSON_CONTAINSまたはJSON_SEARCHで試してみました:User::whereRaw('JSON_CONTAINS(friends->"$.id", "3")')->get()、多くの異なる変形が、何もそれをしません。

ここに来る前に、私はこの問題に関するいくつかの興味深い記事を読んでいますが、これはMySQLデータベースにJSON配列を保存した唯一の人のようです。 ^^

だから、誰も私は、私はそれを本当に感謝し、この問題の解決に役立つことができれば。 サイドノート:私の現在のMySQLバージョンは5.7.11なので、JSONフィールドをサポートしており、Laravelはエラーをスローしません。空の配列を返します。

答えて

1

whereRawの試行は非常に近いです。 1つのオブジェクトを格納していた場合は、パスは$.idになります。しかし、オブジェクトの配列を格納しているので、パスは$[*].idです。これはあなたのために働くべきである。(JSON_EXTRACT()ための単なるショートカットです)

User::whereRaw('JSON_CONTAINS(friends->"$[*].id", "3")')->get(); 

friends->"$[*].id"セレクタは、IDのJSON配列を返します。 JSON_CONTAINS()は、json配列に指定されたidが含まれているかどうかを確認します。

もう1つの方法は、JSON_CONTAINS()に使用するjson検索文字列を作成することです。たとえば、このクエリでも動作するはずです:

User::whereRaw('JSON_CONTAINS(friends, \'{"id": 3}\')')->get(); 

これはJSON_EXTRACT()の最初の呼び出しを回避し、あなたは一つだけのJSONメソッドを呼び出しています。私はどのバージョンが実際に速いのか、何か違いがあるのか​​どうかはわかりません。

また、JSON_SEARCH()に関連するサイドノートでは、この機能は文字列値を検索する場合にのみ機能します。あなたのjsonは、IDが文字列ではなく整数として表されるので、JSON_SEARCH()は機能しません。 MySQLはこれが意図された動作であると主張しています(bug 79233dup bug 79316)。

here is the documentation for the json search methodsです。

+0

あなた、私の日を作ったばかりです!どうもありがとうございました。 **両方のソリューションが動作します**、私はおそらく後者を使用しています。より洗練された、より多くのJSONのようなものを見つけて、ほんの1つのjsonメソッドを呼び出します。 非常に単純ですが、完全な答えをいただきありがとうございます。 –

関連する問題