reverse() on querybuilder get() changes the collection results

laravel query builder
laravel reverse a collection
laravel add to collection
eloquent select
reverse array laravel
laravel firstwhere
laravel exists
eloquent join

I need to get last 10 records of a table ordered by a data, and reverse them.

This is the code before the reverse:

$eventi = \App\Model::with('relation_1', 'relation_2')
    ->orderBy('data_ora', 'desc')
    ->take(10)
    ->get();

If I log the results I get this:

[{"id":12297,"stato_batteria":null,"data_ora":"2018-05-03 11:40:02" ...

The reverse code is:

$eventi = \App\Model::with('relation_1', 'relation_2')
    ->orderBy('data_ora', 'desc')
    ->take(10)
    ->get()
    ->reverse();

If I log the results I get this:

{"9":{"id":1410,"stato_batteria":null,"data_ora":"2018-04-05 14:16:48" ...

As you can see the collection is changed and I do not know why.

Use this to reset the keys:

->reverse()->values();

Return collection from the query builder · Issue #10478 · laravel , Not the end of the world, but definitely a breaking change. As you said, though, the backwards compatibility penalty is in a really bad shape (and hugely between Eloquent and Query Builder get() methods. — It's not that turning the DB result into a collection is irreversible – you can always access the  as mentioned in collection documentation of laravel, when u apply reverse method to a collection, the collection order will change. in ur case here u get ur data collection order by data_ora and desc, when u apply reverse after get, that means u will reverse the collection to be ordered by data_ora but ASC not DESC.

When you do this:

$eventi = \App\Model::with('relation_1', 'relation_2')
    ->orderBy('data_ora', 'desc')
    ->take(10)
    ->get();

You get a Collection object, containing those values. The keys of the values in the underlying array will be numeric, i.e. 0, 1, 2, ... 9. Now when you're doing:

$eventi = \App\Model::with('relation_1', 'relation_2')
    ->orderBy('data_ora', 'desc')
    ->take(10)
    ->get()
    ->reverse();

You're getting the same collection back, in reverse order. The reverse method creates a new collection, but preserves the keys of the original collection. So in this case you'll be seeing the last item, first and the keys will be 9, 8, 7, ... 0. In PHP, if your array keys aren't integers, in ascending order starting from 0, it is assumed to be an associative array. So when you're outputting your collection as JSON you're seeing it represented as an object.

A way to ignore the keys in the collection is to use values, so that a new collection is created (with ascending numeric keys i.e. 0, 1, 2, ... 9), only with the values of the initial collection:

$eventi = \App\Model::with('relation_1', 'relation_2')
    ->orderBy('data_ora', 'desc')
    ->take(10)
    ->get()
    ->reverse()
    ->values();

Retrieving Data & Results Sets - 3.8, The return value of any find() method is always a Cake\ORM\Query object. $​results = $query->all(); // Once we have a result set we can get all the rows $data Once you've started a query you can use the Query Builder interface to build more This function will change the query so that it filters results that have no  Plan to transform queries and order results in SharePoint Server. 7/25/2017; 11 minutes to read +5; In this article. APPLIES TO: 2013 2016 2019 SharePoint Online You can add query transforms to a Web Part, add query rules that transform queries when certain conditions are met, and you can transform all queries directed to a result source to create a specialized search experience.

as mentioned in collection documentation of laravel, when u apply reverse method to a collection, the collection order will change.

in ur case here u get ur data collection order by data_ora and desc,

when u apply reverse after get, that means u will reverse the collection to be ordered by data_ora but ASC not DESC.

in other words, the first element of collection will be the last ...

check the laravel documentation here reverse method

Query Builder - 3.8, The ORM's query builder provides a simple to use fluent interface for creating and running calling toList() or some of the methods inherited from Collection, will result in the You can use the first() method to get the first result in the query: When fetching entities that don't change often you may want to cache the results. All multi-result sets returned by Eloquent are instances of the Illuminate\Database\Eloquent\Collection object, including results retrieved via the get method or accessed via a relationship. The Eloquent collection object extends the Laravel base collection , so it naturally inherits dozens of methods used to fluently work with the underlying

The QueryBuilder, There're currently 3 possible return values for getType() : QueryBuilder::SELECT , which returns value 0; QueryBuilder::DELETE , returning value 1  {note} When updating or deleting records inside the chunk callback, any changes to the primary key or foreign keys could affect the chunk query. This could potentially result in records not being included in the chunked results. Aggregates. The query builder also provides a variety of aggregate methods such as count, max, min, avg, and sum. You may call any of these methods after constructing your query:

Collections - Laravel, Getting Started · Query Builder · Pagination · Migrations · Seeding · Redis The results of Eloquent queries are always returned as Collection instances. filter first firstWhere flatMap flatten flip forget forPage get groupBy has implode pull push put random reduce reject replace replaceRecursive reverse search shift  However, the query builder's cursor method returns a LazyCollection instance. This allows you to still only run a single query against the database but also only keep one Eloquent model loaded in memory at a time.

Code Bright: Eloquent Collections, Don't worry, you can still iterate through a collection of results with the variety of loops that The all() method can be used to get hold of the internal array used by the Collection object. We then iterate through the $reverse collection to see what has changed. We can use the first() method on the Eloquent query builder​. A reverse stock split results in an increase in the price per share. A stock split , on the other hand, is when a company increases the number of shares outstanding by splitting them into multiple

Comments
  • What do you mean that the collection has changed? You've called reverse which returns a new collection with the items in reverse order.
  • if the collection is not changed, why the 2 collections, written on the log file, are different?
  • Did you expect the two outputs to be the same? If not, what did you expect to happen?
  • I expect the 2 collections are the same json object, just reverse. If you see what I get in the log you see you have 2 different objects.
  • I can't see enough data to make that assumption, can you post your full logs for those two calls?
  • Finally I got an answer! Thanks! Only reverse() doesn't work properly.
  • Thanks, it is what I needed.
  • I wrote what I get if I log the 2 collections, and they are 2 different json objects.