217

let's say I run this query in Mongoose:

    Room.find({}, (err,docs) => {
    
    }).sort({date:-1}); 

This doesn't work!

Akash Kumar Verma
  • 3,185
  • 2
  • 16
  • 32
TIMEX
  • 259,804
  • 351
  • 777
  • 1,080

11 Answers11

556

Sorting in Mongoose has evolved over the releases such that some of these answers are no longer valid. As of the 4.1.x release of Mongoose, a descending sort on the date field can be done in any of the following ways:

    Room.find({}).sort('-date').exec((err, docs) => { ... });
    Room.find({}).sort({date: -1}).exec((err, docs) => { ... });
    Room.find({}).sort({date: 'desc'}).exec((err, docs) => { ... });
    Room.find({}).sort({date: 'descending'}).exec((err, docs) => { ... });
    Room.find({}).sort([['date', -1]]).exec((err, docs) => { ... });
    Room.find({}, null, {sort: '-date'}, (err, docs) => { ... });
    Room.find({}, null, {sort: {date: -1}}, (err, docs) => { ... });

For an ascending sort, omit the - prefix on the string version or use values of 1, asc, or ascending.

Minsky
  • 2,277
  • 10
  • 19
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • 3
    +1 for showing tons of different ways it can be done. However, I can't find in the docs that [Query#find](http://mongoosejs.com/docs/api.html#query_Query-find) will take that many arguments. The signature is `Query#find([criteria], [callback])`. I thought maybe there was some secret handshake that says "criteria" can be up to three arguments, but it lists the type as "Object". – Nateowami Feb 17 '17 at 14:46
  • @Nateowami You're looking at the wrong `find` method in the docs. See [`Model.find`](http://mongoosejs.com/docs/api.html#model_Model.find). – JohnnyHK Feb 17 '17 at 14:49
  • 1
    You're right. I saw they were using the `Module#property` notation and searched for `#find`. It seems there is no easy way to navigate or search the docs. Searching for find yields 187 results. – Nateowami Feb 17 '17 at 16:41
  • 4
    You can also sort by the `_id` field. For example, to get the most recent record, you can do: `await db.collection.findOne().sort({ _id: -1 });` – Mike K Feb 08 '20 at 11:00
59

The correct answer is:

Blah.find({}).sort({date: -1}).execFind(function(err,docs){

});
Timm
  • 2,652
  • 2
  • 25
  • 34
TIMEX
  • 259,804
  • 351
  • 777
  • 1,080
17

Been dealing with this issue today using Mongoose 3.5(.2) and none of the answers quite helped me solve this issue. The following code snippet does the trick

Post.find().sort('-posted').find(function (err, posts) {
    // user posts array
});

You can send any standard parameters you need to find() (e.g. where clauses and return fields) but no callback. Without a callback it returns a Query object which you chain sort() on. You need to call find() again (with or without more parameters -- shouldn't need any for efficiency reasons) which will allow you to get the result set in your callback.

Jimmy Hillis
  • 321
  • 2
  • 4
9
Post.find().sort({date:-1}, function(err, posts){
});

Should work as well

EDIT:

You can also try using this if you get the error sort() only takes 1 Argument :

Post.find({}, {
    '_id': 0,    // select keys to return here
}, {sort: '-date'}, function(err, posts) {
    // use it here
});
mrid
  • 5,782
  • 5
  • 28
  • 71
lynx_vbg
  • 183
  • 1
  • 5
4

I do this:

Data.find( { $query: { user: req.user }, $orderby: { dateAdded: -1 } } function ( results ) {
    ...
})

This will show the most recent things first.

Noah
  • 4,601
  • 9
  • 39
  • 52
  • 1
    [`$orderby`](https://docs.mongodb.com/manual/reference/operator/meta/orderby/) is deprecated in MongoDB 3.2 so it shouldn't be used anymore. – JohnnyHK Jun 22 '16 at 22:12
3

All the anwsers here are factually correct, however I am writing my anwser to make it clear that sometimes writing '-date' or date: -1 won't work if you either don't have a field named 'date' in your model, or if you passed the option: timestamps: true in options when creating your model. If you are using timestamps: true then you need to type: sort({createdAt: -1}) and this will work then.

ms3300
  • 216
  • 6
  • 13
2

Short solution:

const query = {}
const projection = {}
const options = { sort: { id: 1 }, limit: 2, skip: 10 }

Room.find(query, projection, options).exec(function(err, docs) { ... });
davidsonsns
  • 361
  • 6
  • 4
2

See if this helps > How to sort in mongoose?

Also read this > http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order

Community
  • 1
  • 1
neebz
  • 11,465
  • 7
  • 47
  • 64
  • That 1st method doesn't work. It just hangs...I think it's because of an update in mongoose.... And the 2nd method is just the mongo docs, which I know about. – TIMEX Apr 28 '11 at 23:25
  • The find() function is MongoDB's function, not Mongoose. Please read Mongoose API page for more details You can use the syntax defined in MongoDB docs with Mongoose. That's why Mongoose doesn't have its own sorting or intersect queries. – neebz Apr 29 '11 at 10:40
2

You can also sort by the _id field. For example, to get the most recent record, you can do,

const mostRecentRecord = await db.collection.findOne().sort({ _id: -1 });

It's much quicker too, because I'm more than willing to bet that your date field is not indexed.

Mike K
  • 7,621
  • 14
  • 60
  • 120
2

This one works for me.

`Post.find().sort({postedon: -1}).find(function (err, sortedposts){
    if (err) 
        return res.status(500).send({ message: "No Posts." });
    res.status(200).send({sortedposts : sortedposts});
 });`
Usama Tahir
  • 1,235
  • 12
  • 14
2

ES6 solution with Koa.

  async recent() {
    data = await ReadSchema.find({}, { sort: 'created_at' });
    ctx.body = data;
  }
chovy
  • 72,281
  • 52
  • 227
  • 295