Laravel: Querying JSON column containing array, expecting similar results to "whereIn" - php

I have a database column called support_tags. This is a jsonb column containing a simple array that looks like:
[
"caring",
"budgets",
"careers_employment",
"addictions"
]
I am attempting to query this column using the following:
$services = \App\Models\Service::where("status", "accepted")->whereRaw("JSON_CONTAINS(support_tags, '" . json_encode($categories) . "')")->get();
This doesn't retrieve the results I am hoping for/expecting. If I send the following array:
[
"caring",
"smoking"
]
The results I get back are services that contain all array elements. I need this to work more like a whereIn, in that not all array values need to be present in the database column, but one or more. If anyone knows of a way to do this I'd be very grateful. Thanks.

you can use these eloquent methods: ->whereJsonContains() and ->orWhereJsonContains()
your query will be like this:
$services = \App\Models\Service::where("status", "accepted")
->where(function($query) {
$query->whereJsonContains('support_tags', 'smoking')
->orWhereJsonContains('support_tags', 'caring');
});

Just before I accept the other answer to this question, I thought it may be useful to share my implementation of this which is based on the accepted answer This does the trick:
$categories = request()->infoAdviceCategories;
$services = [];
if (count($categories)) {
$services = \App\Models\Service::where("status", "accepted")->whereJsonContains("support_tags", $categories[0]);
foreach ($categories as $category) {
if ($category !== $categories[0]) {
$services->orWhereJsonContains("support_tags", $category);
}
}
$services = $services->get();
}
return $services;

Related

how to search a array of objects with array property in laravel

i want query a table with a json column
the object stored in json column is like this:
[
{
"title":"first",
"ids":[79,583,584]
},
{
"title":"second",
"ids":[600,601,602]
},
{
"title":"third",
"ids":[605,606,624]
}
]
and for example i want to find a row where one of its ids property contain for example 79. something like this:
Model::query()->whereJsonContains('data', ['ids[*]' => 79])->first();
i,ve searched a lot and tried some syntaxes but nothing worked. is that possible to do? how?
my database is mysql
querying nested json formats might not be available as of now, you can try filtering the eloquent collection though.
you have to cast the json data column as array on your model first and then filter the collection as per your conditions.
$id = 8;
$filtered = Model::all()->filter(function($item, $key) use($id) {
$count = 0;
foreach($item->data as $data) {
if(in_array($id, $data['ids'])) {
$count += 1;
}
}
return $count > 0;
})->all();

how can get a specific value from database in using php laravel model

function subscriptionpack(Request $request)
{
$sub = subscription::all();
$details = $sub['details'];
dump('$details');
}
I can get all values from this code, but I can't get the specific field that named details. When I call dump($sub) it was shown all details, but the dump('$details') make an error that is undefined index:details
anyone can help me to correct this code?
You can use select method to select specific column data :
$sub = subscription::select('details')->get();
Or, you can do with on get() method as like :
$sub = subscription::get(['details']);
If you need single column from the result set use pluck
$subs = subscription::all();
$details = $subs->pluck('details')->toArray();
You can either loop over to your collection e.g
foreach($sub as $s){
dump($s->details)
}
or you can try something like.
$sub->first()->details
but this will give you only first details element from your collection.
First a model should be in singular, no spacing between words, and capitalised.
You should use Subscription::all(); not subscription::all();. You should read Laravel conventions
use App\Subscription;
..
function subscriptionpack(Request $request)
{
$sub = Subscription::all()->pluck('details');
dd($sub);
}

Get all elements of array in query laravel

I am trying to loop in an array but when it comes to the query it gets only the first element, so a little help would be very important.
$data = Offers::whereIn('id_business', $business_id_array)
->where([
'visible' => 'yes',
'delete' => 'no'
])
->where('end_date', '>=', date('Y-m-d h:m:i'))
->orderBy('id', 'desc')
->get();
$data=array($data);
foreach($data as $key => $item) {
$offers = DB::select('the data i need to get WHERE o.`id` = ' . $item[$key]['id']);
}
and this is my problem in here, It gets only the id of the first element
o.`id` = ' . $item[$key]['id']
because you have return the view in side the foreach loop, so it only loop through the first item and return. What you can do with this case is
$data = Offers::whereIn('id_business', $business_id_array)...->get()->toArray();
$offers = array_map(function($item){
$offer = DB::select('the data i need to get WHERE o.`id` = ?', [$item->id]);
return $offer;
},$data);
return view(....,['offers' =>$offers]);
First, you do not need to cast the $data to an array - it will get returned as a collection, which you can iterate through like an array. So you'll be able to use something like this
$offers = Offers::whereIn('id_business', $business_id_array)...->get();
foreach ($offers as $offer) {
$moreData = DB::select('the data i need to get WHERE o.`id` = ?', [$offer->id]);
}
This looks like you are using the id from one table, to get the associated data from another table.
Should there not be a relationship in place, between the two tables?
The answer from #Chris G looks correct, maybe dd($offers) to be certain what is in there.
Mick

Extract all possible values of AR column in yii2

Several models in yii2 are bound to a database using ActiveRecords. I now want to have a list of all ids of this model. Say, all user IDs when the Model is called User.
Sure I could just fetch all models and iterate over them, much like
$ids = [];
$users = User::find()->all();
foreach ($users as $user) {
$ids[] = $user->id;
}
But I feel there should be an easier way... Thanks in advance.
If you want to stay in ActiveRecord then this accomplishes the same thing:
$ids = User::find()->select('id')->column();
This returns array:
$ids = (new \yii\db\Query)->select('id')->from(User::tableName())->all();

Convert database values to JSON, without column names

I'm trying to get a list of categories and return them as JSON for an AJAX call, but Laravel is including column names too, which I don't need.
$categories = Category::where('parent', '=', '0')->select('name')->get();
return response()->json($categories);
This way I get
[{"column_name", "value"}]
And I want
{"value1", "value2"}
Thanks!
Try this: $arr = json_decode($categories, true). Then deal with the array output it gives.
You simply use eloquent's lists method
$categories = Category::where('parent', '=', '0')->select('name')->lists('name');
return response()->json($categories);
Use array_values function to get the values array.
And {"value1", "value2"}the format is invalid of Json . Valid format ["value1","value2"] . If use { } means to Object ,but object must have key=>value.
$categories = Category::where('parent', '=', '0')->select('name')->get();
return response()->json(array_values($categories));

Categories