33

i'm quite new to mongodb. i manage to get a basic idea of a simple sort based only 1 parameter. what if there are more than 2 sort parameters. for instance, in a database made up of woodworking projects that have attributes totalCuttingTime and favorited.

Is the following a correct mongoose/mongodb function to find a list of projects that have the least totalCuttingTime and order in according to highest favoriteCounts to lowest.

var ProjectModel= mongoose.model('Project', schema);

exports.getMinCuttingTime = function(number, callback){ 
    var leastCutTimeResult = ProjectModel.find().sort({totalCuttingTime: 1}).select({_id: 1}).limit(number).exec(
            function(err, projects) {
                callback(null, projects)
            }
        );

    var result = leastCutTimeResult.find().sort({favoriteCount: -1}).select({_id: 1}).limit(number).exec(
            function(err, projects) {
                callback(null, projects)
            }
        ); 

    return result;
}
3
  • it is correct. Sort by two fields in Mongo is the same as doing order by A, B in SQL query. Commented Nov 26, 2012 at 16:10
  • @AsyaKamsky and is the syntax correct? where ProjectModel comes from mongoose.model('Project, schema) Commented Nov 26, 2012 at 16:17
  • sorry, can't tell you - I was commenting on the approach being correct - selecting the smallest value for totalCuttingTime and then selecting and sorting by another value all documents which have that totalCuttingTime. Commented Nov 26, 2012 at 20:05

1 Answer 1

81

You need to put both sort terms into one object:

exports.getMinCuttingTime = function(number, callback){ 
    ProjectModel.find()
        .sort({totalCuttingTime: 1, favoriteCount: -1})
        .select({_id: 1})
        .limit(number)
        .exec(
            function(err, projects) {
                callback(null, projects)
            }
        );
};

It's worth noting that the ECMA-262 standard on which Node.js is based doesn't specify that an object's property order is maintained, and it's only a de facto standard to match insertion order. To eliminate any doubt, you can use an array instead:

.sort([['totalCuttingTime', 1], ['favoriteCount', -1]])
Sign up to request clarification or add additional context in comments.

5 Comments

Given that object keys in JavaScript are technically unordered, is this guaranteed to sort by totalCuttingTime first, followed by favouriteCount?
@JohnnyHK I have been looking for a documentation on sort Mongoose and MongoDb, both define sort(<Object, String>) Mongoose Query#sort. Any link defining the sort with array definition ?
@pravin The native driver docs for Cursor#sort include the array style.
This being a nodejs specific feature should have been included in the mongoose docs.. Not sure why its not included.. anyways thank you
Apparently sorting by array is no longer possible; either an object or string is required. Not clear if order is preserved when passing an object, but seems to be when passing a string: mongoosejs.com/docs/api.html#query_Query-sort

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.