Reputation: 5860
I want to fetch the latest document, which obviously is a single document, thus findOne
should work fine. But findOne
here returns the first document inserted. So I have two options now either use $orderBy
with findOne
or use .sort()
function with .limit()
in find()
Using $orderBy it would look something like:
db.collection.findOne({$query:{},$orderby:{_id:-1}})
And using sort:
db.collection.find().sort({_id:-1}).limit(1).pretty()
Both work fine, I just wanted to know which query should I prefer here? In terms of performance, or does both of them work the same way internally and there is no such difference between the two.
Upvotes: 22
Views: 49761
Reputation: 23492
As of Mongo 3.2, $orderby
is deprecated.
The docs explicitly say:
The $orderby operator is deprecated. Use cursor.sort() instead.
Unfortunately, findOne()
doesn't support the sort()
method, so you'll need to switch to find()
:
db.collection.find({}).sort({'key': -1}).limit(1)
This will return a cursor
, so you'll then need to pull the first result from the cursor.
Upvotes: 45
Reputation: 43884
They are the same and in fact the documentation page for $orderby
actually talks mostly about the sort()
function that is provided.
These query modifiers that allow you to add sections of a query on without using the functional accessors do exist but there is a bug mixing these two together so I would recommend you pick either the query modifiers or the functional methods and stick to that option.
In attempting to provide example code I have also found out one other thing when I looked at your question again. You provide:
db.collection.findOne({"$query":{},"$orderby":{ "_id": -1 }})
But it is good to note that:
db.collection.findOne({}).sort({ "_id":-1})
Actually produces:
2014-07-31T04:59:50.183-0700 TypeError: Object [object Object] has no method 'sort'
and as you can see here by my test data set:
> db.rooms.find()
{ "_id" : ObjectId("53ad206e1d8f2d8351182830"), "id" : 1, "from" : ISODate("2014-06-26T00:00:00Z"), "to" : ISODate("2014-06-28T00:00:00Z") }
{ "_id" : ObjectId("53ad276f1d8f2d8351182831"), "id" : 1, "from" : ISODate("2014-06-24T00:00:00Z"), "to" : ISODate("2014-07-01T00:00:00Z") }
{ "_id" : ObjectId("53ad28ad1d8f2d8351182832"), "id" : 1, "from" : ISODate("2014-06-20T00:00:00Z"), "to" : ISODate("2014-06-28T00:00:00Z") }
{ "_id" : ObjectId("53ad28c61d8f2d8351182833"), "id" : 1, "from" : ISODate("2014-06-20T00:00:00Z"), "to" : ISODate("2014-07-03T00:00:00Z") }
{ "_id" : ObjectId("53ad29971d8f2d8351182834"), "id" : 1, "from" : ISODate("2014-06-20T00:00:00Z"), "to" : ISODate("2014-06-21T00:00:00Z") }
the answer is actually correct:
> db.rooms.findOne({ "$query":{}, "$orderby":{ "_id": -1 }})
{
"_id" : ObjectId("53ad29971d8f2d8351182834"),
"id" : 1,
"from" : ISODate("2014-06-20T00:00:00Z"),
"to" : ISODate("2014-06-21T00:00:00Z")
}
So it is interesting to note that query modifiers are supported by findOne
where as functional accessors are not, which could be a reason to use query modifiers instead.
Upvotes: 22