Laravel Eloquent query JSON column with Where In? - php

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"]

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)

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();

Related

Laravel 5.4 query on a JSON field containing a JSON array

Inside users table I have a json column named "agencies" that stores data as a simple array like this:
[
"0eb2edf0-50cb-44ff-a0a6-b2a104a9dc12",
"f7c748d4-8718-441e-aa69-91b890ead5ed"
],
the above is valid json. When I try to select all users that contain 0eb2edf0-50cb-44ff-a0a6-b2a104a9dc12 I get null
Is my query correct?
$users = User::whereRaw('JSON_CONTAINS(agencies->"$[*]", "0eb2edf0-50cb-44ff-a0a6-b2a104a9dc12")')->get();
is the below correct way to do write JSON select query conbsidering how I store uuids as an array inside agencies column which is defined as json?
'JSON_CONTAINS(agencies->"$[*]", "0eb2edf0-50cb-44ff-a0a6-b2a104a9dc12"
I got the idea for above select from reading: Making a Laravel 5.4 query on a JSON field containing a JSON array
but the solution in that post is different then what I am trying to do and my modification to it does not give me back any users, but instead I allways get null back.
I believe that's what you want:
$users = User::whereRaw('JSON_CONTAINS(agencies, ?)', ['0eb2edf0-50cb-44ff-a0a6-b2a104a9dc12'])->get();
It will also soon be supported with the query builder. See PR
MySQL expects a JSON string:
$users = User::whereRaw('JSON_CONTAINS(agencies, ?)',
['"0eb2edf0-50cb-44ff-a0a6-b2a104a9dc12"'])->get();
$users = User::whereRaw('JSON_CONTAINS(agencies, ?)',
[json_encode('0eb2edf0-50cb-44ff-a0a6-b2a104a9dc12')])->get();

Laravel convert resultset to array

Database table SITE has many columns. One of them is site_id. I need all the site_ids as an array since it has to be fed to a method which accepts only a string array.
What I tried so far is:
$sites = DB::select('select site_id from site_tab');
$sites_arr = $sites->toArray();
But this doesn't produce the result I want. I need $sites_arr to be like ['A','B','C',...]
Please suggest a way to get this done. A solution based on Eloquent is also OK for me.
Thanks
Try this:
DB::table('site_tab')->pluck('site_id')->toArray();
reference pluck
referen toArray
If you open a manual, you will see that
The select method will always return an array of results
So, there's no need to use ->toArray(), as result is already an array.
To get values as array of names you can do:
$site_ids = DB::table('site_tab')->pluck('site_id');
Using ->toArray() here is optional, as you can iterate over $site_ids (which is a Collection) with a foreach too.

Laravel Multiple wherein's

How can I do multiple wherein in laravel?
$devices = DB::table('foo')
->select('foo.*')
->whereIn('bar1', $request->bar1)
->whereIn('bar2', $request->bar2)
->get();
Above is my sample code but it is returning me an empty array.
It is ok to use multiple WHERE IN constraints in your query. The code you provided is also ok.
If you're getting no results, make sure that values of $request->bar1 and $request->bar2 are what you expect - they should be arrays of values that contain what you want your bar1/bar2 columns to be.
You can always get the generated SQL by calling toSql() instead of get(), you can also inspect the values of parameters by calling getBindings().

Simplifying the output of a Laravel model query

Suppose I run the following and need to know the results in an easy to examine format:
$orders = Order::where('status', $value);
How would I show something that doesn't display the entire model object, only the records retrieved, when I do dd($orders)?
You may try this:
$orders = Order::where('status', $value)->get();
dd($orders->toArray()); // Outputs only an array of records retrieved from db
There is also toJson() to convert into json string but it's possible to get json representation of the data by returning it from the controller/function, for example:
return Order::where('status', $value)->get(); // Output will be in json format
Instead of dding, just return the model directly from your route/controller:
return Order::where('status', $value)->get();
This will automatically convert it to JSON.
For even better inspection, install the JSON View Chrome extension; it'll format your JSON nicely, and allow you to inspect it beautifully.

Need a INT from Eloquent. Getting JSON string

I have this query:
static function findIdOnName($pageName){
return Fanpages::select('id')
->where('url', '=', $pageName)
->get();
}
Response: (when done print_r)
[{"id":17}]
I just want the INT (in this case 17) I searched the interwebs for it, but I can't find anthing about it. Randomly tried adding ->toString() etc to the query, but so far, no good.
Your code returns a Collection with a single Model (or multiple models if there are more matching the where clause), while the method you need is pluck:
return Fanpages::where('url', '=', $pageName)->pluck('id');
// returns INT 17
as it returns value for column id of the first row matching WHERE clause.
If you do not return a view with data, then Laravel will automatically convert your data into json. In order to accomplish what you want you can simply do something like
$data = Fanpages::select('id')->where('url', '=', $pageName)->get();
die($data->id);
However, exiting the application like this isn't recommended. You should either keep the json response and work with that, or send the data to a basic blade template.

Categories