QueryBuilder中get()后调用reverse()引发集合结果变更的技术咨询
Hey there! Let's break down why using reverse() is causing unexpected changes to your collection, and walk through the proper solutions to get the result you want.
Why reverse() is causing issues
When you call get() to fetch your collection, then chain reverse(), it does flip the order of the records—but it keeps the original collection's keys intact. For example:
- Your initial query returns the 10 newest records, sorted from newest to oldest, with keys
0(newest) to9(oldest in this subset). - After
reverse(), the oldest record in the subset moves to position 0, but its key is still9, and the newest moves to the end with key0.
This creates a collection with non-continuous keys, which can cause problems if you convert it to an array (toArray()) or use it in contexts that expect sequential indexes (like frontend rendering loops).
Quick fix: Reset collection keys with values()
The simplest way to fix this is to add values() after reverse(). This method resets the collection's indexes to a continuous sequence (0, 1, 2, ..., 9):
$eventi = \App\Model::with('relation_1', 'relation_2') ->orderBy('data_ora', 'desc') ->take(10) ->get() ->reverse() ->values();
Now you'll have the 10 newest records sorted from oldest to newest, with clean, sequential indexes that work reliably in any context.
Better performance: Handle sorting in the database
If you're working with larger datasets or want to offload all sorting logic to the database (more efficient), use a subquery to first fetch the IDs of the 10 newest records, then query those records sorted in ascending order:
$eventi = \App\Model::with('relation_1', 'relation_2') ->whereIn('id', function ($subquery) { // Subquery grabs IDs of the 10 most recent records $subquery->select('id') ->from((new \App\Model)->getTable()) ->orderBy('data_ora', 'desc') ->take(10); }) ->orderBy('data_ora', 'asc') // Sort these 10 records from oldest to newest ->get();
This approach lets the database handle all sorting, so you get the final sorted collection directly without any post-processing. It's more efficient for large tables and avoids any key-related issues entirely.
Which solution should you pick?
- Use the
reverse()->values()method for small datasets or when you want a quick, readable fix. - Use the database-side sorting method for better performance, especially with larger tables, or if you prefer keeping all data logic in SQL.
内容的提问来源于stack exchange,提问作者Giacomo M

