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.
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.