Reputation: 89
How can I get the last N entries from MongoDB in a ascending order in PHP?
this is the code im using right now the gets me the last 60 entries but it gives me in a descending form I need it in a ascending form.
<?php
header("Content-type: text/json");
require ($_SERVER['DOCUMENT_ROOT'] . '/grafic/mongodb_php/vendor/autoload.php');
$client = new MongoDB\Client;
$traficodb = $client->traficodb;
$trafico_total = $traficodb->trafico_total;
$filter = [];
$options = ['sort' => ['time_stamp' => -1], 'limit' => 60];
$show = $trafico_total->find($filter, $options);
foreach ($show as $collection) {
$json[]= [strtotime($collection["time_stamp"])*1000, (int)$collection["tx"], (int)$collection["rx"]];
}
echo json_encode($json);
?>
For example if I have rows with timestamp: 1,2,3,4,5,6,7,8,9. I want result shown as 5,6,7,8,9 and not as 9,8,7,6,5
Upvotes: 0
Views: 50
Reputation: 151122
If it's only a relatively small number of results which you are not "paging" ( i.e using limit
and skip
) then the most efficient action would be to simply "reverse" the returned results after converting the MongoDB\Driver\Cursor
as returned from MongoDB\Collection::find()
to an "array".
This is what the Cursor->toArray()
method of the driver does, along with array_reverse()
as a standard PHP function.
$filter = [];
$options = ['sort' => ['time_stamp' => -1], 'limit' => 60];
$show = array_reverse($trafico_total->find($filter, $options)->toArray());
Then as you iterate the list the results are in ascending order, being the "reverse" of what the cursor returned them as.
Alternately you could use use aggregate()
$show = $tracfico_total->aggregate([
[ '$match' => [] ],
[ '$sort' => ['time_stamp' => -1 ] ],
# [ '$skip' => $itemsInPage ],
[ '$limit' => 60 ],
[ '$sort' => ['time_stamp' => 1 ] ]
]);
And you would typically $skip
through previous results before applying your limit, then re-sort the final output. But it really does not add much to what the regular query already does, and the regular query probably does it more efficiently.
There generally is little point asking the database to do things that don't actually "reduce" the results to be returned, so you typically would not perform this on the server unless you had something else to do "on the server" with the results which reduced what was to be returned.
The other case would be typically for a "large resultset" which would be more suited to iterating a cursor. In that case the aggregation approach would be recommended as opposed to converting the cursor to an array "in memory" instead of simply iterating the results in the returned order.
Upvotes: 1