8

I am having trouble querying a json column.

Previously my code was

$query->whereIn('user', $users);

Now i have changed the db type to JSON column and am trying to modify the code for the new version.

In RAW MYSQL this works

JSON_CONTAINS(user, '"tom","Bill"') 

But when i put it in eloquent / php it keeps failing or returning noting. Here i am passing in an array of Users, previous using an WhereIn which works in raw SQL

$leads->whereRaw("JSON_CONTAINS(user, '"$users"')")

Any idea how to make it work in Laravel so i can pass in an array of strings, query them against the json column which contains an array of strings too.

My Json colum has data like so

["Paul", "Tom", "Bob"]
3
  • 1
    Don't you need to add it like this? $leads->whereRaw("JSON_CONTAINS(user, '" .$users ."')") Commented Jan 10, 2018 at 13:31
  • Just tied that there, gives a 500, the query executed is JSON_CONTAINS(user, 'Tom'') and it says Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''Tom'')' at line 1 Commented Jan 10, 2018 at 13:36
  • any ideas? i am really stuck with this Commented Jan 10, 2018 at 13:54

3 Answers 3

19

MySQL expects a JSON string:

$leads->whereRaw('JSON_CONTAINS(user, ?)', [json_encode($users)])

In Laravel 5.6.24 you can use whereJsonContains():

$leads->whereJsonContains('user', $users)
Sign up to request clarification or add additional context in comments.

Comments

3

If $users is array of names then you should iterate over it and add orWhereRaw condition, note that orWhereRaw can accept an array of parameter:

 $users = ["Tom", "Bob"];

 foreach( $users as $user) {
      $leads->orWhereRaw("JSON_CONTAINS(user, ?)", [$user]);
 }

 $leads = $leads->get();

5 Comments

When i run this i get back an empty array. what is the ? for in this case?
? represent $user parameter, something like PDO prepared statement, you can't just concatenate $user in the DB::raw because of sql injection attacks
have you tried $leads->whereRaw("JSON_CONTAINS(user, ?)", [$users]); with $users = '"tom","Bill"'
this sql works fine where JSON_CONTAINS(user, '"Paul"') But the code returns just an empty array foreach($users as $u){ $query->whereRaw("JSON_CONTAINS(user, ?)", [$u]); die(var_dump($query->get())); }
You have to use orWhereRaw not whereRaw I think that's why you get empty array
1

You don't necessarily have to use whereRaw. Assume data below is the json column:

$categories = ['category-one', 'category-two', 'category-three'];

Article::where('published', true)
    ->where(function ($query) use ($categories) {

        foreach ($categories as $category) {
            $query->orWhereJsonContains('data->categories', $category);
        }
    })
    ->get();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.