Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose: Sort alphabetically

I have a User model

var User = mongoose.model('Users',
    mongoose.Schema({
        username: 'string',
        password: 'string',
        rights: 'string'
    })
);

I want to get all the users, sorted alphabetically by username. This is what I have tried

User.find({}, null, {sort: {username: 1}}, function (err, users) {
    res.send(users);
});

However, this does not sort the users alphabetically. How can I sort alphabetically?

EDIT: I got confused because I was expecting a "purely alphabetically" sort from Mongoose, not one where Z > a. Basically, I wanted a sort based on username.toLowerCase().

like image 487
Randomblue Avatar asked Jan 11 '13 14:01

Randomblue


People also ask

How do I sort in MongoDB by alphabetical order?

To sort documents in MongoDB, you need to use sort() method. The method accepts a document containing a list of fields along with their sorting order. To specify sorting order 1 and -1 are used. 1 is used for ascending order while -1 is used for descending order.

How do you use Mongoose Paginate?

Try using mongoose function for pagination. Limit is the number of records per page and number of the page. Show activity on this post. var paginate = 20; var page = pageNumber; MySchema.

What is skip in mongoose?

In Mongoose, the skip() method is used to specify the number of documents to skip. When a query is made and the query result is returned, the skip() method will skip the first n documents specified and return the remaining.


2 Answers

This question and answer are a few years old, and from what I can tell there is now a correct way to do this. Providing this for future searchers:

User.find().collation({locale:'en',strength: 2}).sort({username:1})
    .then( (users) =>{ 
        //do your stuff
    });

You could also index on username without case sensitivity:

UserSchema.index({username:1}, {collation: { locale: 'en', strength: 2}});

strength:1 is another option - best to refer to the documentation to decide which works best for you.

For the details of all this, look here.

like image 106
WillyC Avatar answered Oct 11 '22 17:10

WillyC


EDIT: Per the comment the issue turns out to be sorting on toLowerCase(username). MongoDB doesn't have a built in method for complex sorting. So there are essentially two ways to go:

  1. Add a usernameLowerCase field to the Schema. This is the better option if you need to do this a lot.
  2. Perform an aggregation with a projection using the $toLower operator to dynamically generate a usernameLowerCase field. This comes with performance and memory caveats, but it may be the more convenient choice.

Original Answer: Here's a complete example that sorts correctly using the specific code from the question. So there must be something else going on:

#! /usr/bin/node

var mongoose = require('mongoose');
mongoose.connect('localhost', 'test');
var async = require('async');

var User = mongoose.model('Users',
    mongoose.Schema({
        username: 'string',
        password: 'string',
        rights: 'string'
    })
);

var userList = [
    new User({username: 'groucho', password: 'havacigar', rights: 'left'}),
    new User({username: 'harpo', password: 'beepbeep', rights: 'silent'}),
    new User({username: 'chico', password: 'aintnosanityclause', rights: 'all'})
];

async.forEach(userList, 
    function (user, SaveUserDone) {
        user.save(SaveUserDone);
    },
    function (saveErr) {
        if (saveErr) {
            console.log(saveErr);
            process.exit(1);
        }
        User.find({}, null, {sort: {username: 1}}, function (err, users) {
            if (err) {
                console.log(err);
                process.exit(1);
            }
            console.log(users);
            process.exit(0);
        });
    }
);
like image 44
mjhm Avatar answered Oct 11 '22 18:10

mjhm