Combine two queries into one and sort them - php

I am trying to display buildings and circuits in list (only 3 in total, sorted by the column "updated_at"). The problem is that they are not in the same table. I have a table circuits and a table buildings.
I tried to do this:
$buildings = Building::published()->limit(3)->get();
$circuits = Circuit::published()->limit(3)->get();
$merged = $buildings->merge($circuits);
$this->data['buildingsAndCircuits'] = $merged->all();
I get everything right when I'm doing my var_dump and I know how to access the data when I do a foreach. But that does not do what I want.
I would like to sort them (by updated_at) and have only three and not six.
Is there a way to do that?
I tried to make conditions like with the QueryBuilder on $merge but it does not work
$this->data['buildingsAndCircuits'] = $merged->orderBy('updated_at', 'DESC')->limit(3)->all();
thank you very much

Once you've called get on each query then the query is executed and the result is returned. orderBy will not longer work after that since what you have in $buildings, $circuits and $merged is a collection.
You can however do this:
$buildings = Building::published()->limit(3)->get();
$circuits = Circuit::published()->limit(3)->get();
$merged = $buildings->merge($circuits)->sortByDesc('updated_at');
$this->data['buildingsAndCircuits'] = $merged->all();
Check what else you can do on collections in the documentation

Related

Laravel pagination with specific foreign key

I need to make pagination in Laravel, and as I read laravel documentation here is a several way to do it. but in my cases it is a little bit complexity. So let say I've two table in my DB, table1 and table2(many to many relationship), I want to paginate table1 with specific ids. So I mean if table1 contains ids 1,2,3,4,5 ... n, I want to paginate only rows which id is 2 and 3
I have tried :
private function check_wear($type){
$products_id = array(); //here is ids which $type is set as 'ON'
$wears = DB::select("SELECT prod_id FROM wears WHERE ".$type." = 'on' "); //Select specific products ids. (in our case it is **table1**)
foreach ($wears as $wr){
array_push($products_id,$wr->prod_id);
}
return $products_id; //return array with ids which should be paginate
}
public function hat($locale){
$hat_prod_ids = $this->check_wear('coat');
$p=12;
$products = DB::table('products')->paginate($p); // 12 per page
dd($products);
my code only paginate one table with all data, is there any built-in function to somehow write a logic condition? for pagination
If you need to filter your pagination with elements which you've in $hat_prod_ids, you're able to use WhereIn() method, that one checks if your elements (in our case ids) exist in your $hat_prod_ids and returns true or false
$products = DB::table('products')
->whereIn('id',$hat_prod_ids)
->paginate($p);
add that code and now you will be able to paginate only that ids which is matched in your array

how to compare two collection and get match records

I am using Laravel and I have two different collections that contain ID of products
First one is colorProduct and second is tagProduct
so I want to compare these two and get only same ID of products so how can I do this?
$colorProducts = Color::where('code', $request->color)->get()->first()->products;
$tagProducts = $tag->products->where('shop_id', $shop->id);
$colorAndTagProducts = collect();
foreach ($colorProducts->toBase()->merge($tagProducts)->unique('id')->groupBy('id') as $allProducts) {
if ($allProducts->count() >= 1) {
$colorAndTagProducts[] = $allProducts->first();
}
}
here
$colorAndTagProducts
gives me all records form both collection but I only want same record
I dont know, if I understand correctly, but maybe like this?
I suppose Color and Product are in many to many relationship. And Product and Shop/tag in one to many.
$colorId = Color::where('code', $request->color)->get()->first()->id;
$shopId = $shop->id;
$products = Product::whereHas('colors', function ($query) use ($colorId) {
$query->where('id', $colorId); //id or color_id
})->where('shop_id', $shopId)->get();
intersect()
The intersect method removes any values from the original collection
that are not present in the given array or collection. The resulting
collection will preserve the original collection's keys:
I did it with this method

How to get count of each result

How can I get the total number of records for each of the grouped column(some_id) results generated in this eloquent query? (Answers generated using DB query builder or vanilla PHP also welcome).
$results = \App\MyModel::groupBy('some_id')
->whereNotNull('some_id')
// some query here to get sum of each grouped column records
->get();
The desired result would be such that when I'm looping through the results, I can also have a field called for example totalRecords for each grouped results. i.e.
foreach($results as $result) {
echo $result->totalRecords;
}
$results = DB::table('your_table')
->select('some_column_name', DB::raw('count(some_id) as totalRecords'))
->whereRaw('some_id IS NOT NULL')
->groupBy('some_id')
->get();
You can do like this :-
$results = \App\MyModel::select('*', DB::raw('count(some_id) as totalRecords'))
->groupBy('some_id')
->whereNotNull('some_id')
->get();
foreach ($results as $result) {
echo $result->totalRecords;
}
Collection Provide itself count() method.
But sometime once you fetch whole collection using get(). You can use count method on collection something like this:
$results = \App\MyModel::groupBy('some_id')
->whereNotNull('some_id')
// some query here to get sum of each grouped column records
->get();
dd($results->count());
Also, If your data is not collection then Php array's provide you count method you can use that too:
dd(count($results));
I used dd method just for debuging purpose.That will show you result before actual output.
count() method of array will help you to count collection as well as sub collection or array of sub array.
Good luck !!!

Yii findAllByPk without ordering

I have an array of Ids which has already been ordered based on some criterias
Example:
$array = array(5,4,10,3,1);
and i am using yii to get all these records from database:
$records = TableName::model()->findAllByPk($array);
this is returning me the correct results but its being sorted by the primary key in ascending order.
i even tried using CDbCriteria like this:
$criteria = new CDbCriteria();
$criteria->addInCondition('primaryKeyColumnName',$array);
$records = TableName::model()->findAll($criteria);
and its still being sorted.. can anyone help me plz
Add This line and try I think It will work as you want.
$criteria->order = "FIELD(id, '5,4,10,3,1')";

iterate all documents->_ids in mongodb, php

I'm currently doing this:
$t_category = 781;
$res = $collection->findOne(array("_id" => intval($t_category)));
this way i am getting only one category (it was just to try). How can I get all categories (documents->_ids) in php->mongo? A way I could iterate over all the documents in the collection. I have tried the find with no arguments. No luck. Any idea?
Calling find with no arguments will return all items in the collection.
$results = $collection->find();

Categories