59
votes

I am trying to retrieve one element from a mongo collection, the one with the greatest _id field. I know this can be done by querying:

db.collection.find().sort({_id: -1}).limit(1)

But it kind of seems unelegant and I was wondering whether there is a way to get that specific element using findOne()

Note: I want to do this because, from what I've read in ObjectId, the first bytes correspond to the miliseconds since the Epoch and thus, the last element being inserted will have the greatest _id. Is there any other way to retrieve the last element inserted in a collection?

5
There's nothing inelegant about your original method, actually.JohnnyHK
Reminder that the ObjectId is usually created by the client driver, so it's only as accurate/reliable as the clients being used. If two drivers insert at the same second, the results won't be predictable.WiredPrairie

5 Answers

93
votes

You should use find, like you already are, and not aggregation which will be slower since it needs to scan all the values of _id fields to figure out the max.

As comments pointed out there is no difference between using find() and findOne() - functionally or elegance-wise. In fact, findOne in the shell (and in the drivers which implement it) is defined in terms of find (with limit -1 and with pretty print in the shell).

If you really want to do the equivalent of

db.collection.find().sort({_id:-1}).limit(1).pretty()

as findOne you can do it with this syntax:

db.collection.findOne({$query:{},$orderby:{_id:-1}})
12
votes

You can get max _id using aggregation of mongodb. Find and sort may overkill's.

db.myCollection.aggregate({
    $group: {
        _id: '',
        last: {
            $max: "$_id"
        }
    }
});
1
votes

with PHP driver (mongodb)
using findOne()

$filter=[];
$options = ['sort' => ['_id' => -1]]; // -1 is for DESC
$result = $collection->findOne(filter, $options);
$maxAge = $result['age']
0
votes
import pymongo

tonystark = pymongo.MongoClient("mongodb://localhost:27017/")

mydb = tonystark["tonystark_db"]
savings = mydb["customers"]

x = savings.find().sort("_id")
for s in x:
    print(s)
-1
votes
$maxId="";

$Cursor =$collection->find();

foreach($cursor as $document) { 
    $maxid =max($arr=(array($document['id'])));
}

print_r($maxid+1);