MongooseJS - How to find the element with the maximum value?

30,989

Solution 1

Member
  .findOne({ country_id: 10 })
  .sort('-score')  // give me the max
  .exec(function (err, member) {

    // your callback code

  });

Check the mongoose docs for querying, they are pretty good.

If you dont't want to write the same code again you could also add a static method to your Member model like this:

memberSchema.statics.findMax = function (callback) {

  this.findOne({ country_id: 10 }) // 'this' now refers to the Member class
    .sort('-score')
    .exec(callback);
}

And call it later via Member.findMax(callback)

Solution 2

You do not need Mongoose documentation to do this. Plain MongoDb will do the job.

Assume you have your Member collection:

{ "_id" : ObjectId("527619d6e964aa5d2bdca6e2"), "country_id" : 10, "name" : "tes2t", "score" : 15 }
{ "_id" : ObjectId("527619cfe964aa5d2bdca6e1"), "country_id" : 10, "name" : "test", "score" : 5 }
{ "_id" : ObjectId("527619e1e964aa5d2bdca6e3"), "country_id" : 10, "name" : "tes5t", "score" : -6 }
{ "_id" : ObjectId("527619e1e964aa5d2bdcd6f3"), "country_id" : 8, "name" : "tes5t", "score" : 24 }

The following query will return you a cursor to the document, you are looking for:

 db.Member.find({country_id : 10}).sort({score : -1}).limit(1)

Solution 3

It might be faster to use find() than findOne().

With find().limit(1) an array of the one document is returned. To get the document object, you have to do get the first array element, maxResult[0].

Making Salvador's answer more complete ...

var findQuery = db.Member.find({country_id : 10}).sort({score : -1}).limit(1);

findQuery.exec(function(err, maxResult){
    if (err) {return err;}

    // do stuff with maxResult[0]

});

Solution 4

This is quick and easy using the Mongoose Query Helpers.

The general form for this could be:

<Your_Model>.find()
   .sort("-field_to_sort_by")
   .limit(1)
   .exec( (error,data) => someFunc(error,data) {...} );

tldr: This will give you an array of a single item with the highest value in 'field_to_sort_by'. Don't forget to access it as data[0], like I did for an hour.

Long-winded: Step-by-step on what that string of functions is doing...

Your_Model.find() starts the query, no args needed.

.sort("-field_to_sort_by") sorts the everything in descending order. That minus-sign in front of the field name specifies to sort in descending order, you can discard it to sort in ascending order and thus get the document with the minimum value.

.limit(1) tells the database to only return the first document, because we only want the top-ranked document.

.exec( (error,data) => someFunc(error,data) {...} ) finally passes any error and an array containing your document to into your function. You'll find your document in data[0]

Solution 5

You can also use the $max operator:

// find the max age of all users
Users.aggregate(
    { $group: { _id: null, maxAge: { $max: '$age' }}}
  , { $project: { _id: 0, maxAge: 1 }}
  , function (err, res) {
  if (err) return handleError(err);
  console.log(res); // [ { maxAge: 98 } ]
});
Share:
30,989
geeky_monster
Author by

geeky_monster

Updated on May 22, 2020

Comments

  • geeky_monster
    geeky_monster almost 4 years

    I am using MongoDB , MongooseJS and Nodejs.

    I have a Collection ( called Member ) with the following Fields -

    Country_id , Member_id , Name, Score

    I want to write a query which returns the Member with the max Score where Country id = 10

    I couldnt find suitable documentation for this in MongooseJS.

    I found this at StackOVerflow ( this is MongoDB code )

    Model.findOne({ field1 : 1 }).sort(last_mod, 1).run( function(err, doc) {
         var max = doc.last_mod;
    });
    

    But how do I translate the same to MongooseJS ?