smilexu
smilexu

Reputation: 1553

How to get all count of mongoose model?

How can I know the count of a model that data has been saved? there is a method of Model.count(), but it doesn't seem to work.

var db = mongoose.connect('mongodb://localhost/myApp');
var userSchema = new Schema({name:String,password:String});
userModel =db.model('UserList',userSchema);        
var userCount = userModel.count('name');

userCount is an Object, which method called can get a real count?

Thanks

Upvotes: 155

Views: 311780

Answers (9)

Udith Chandrarathna
Udith Chandrarathna

Reputation: 324

Model.count() method is deprecated in mongoose version 6.2.0. If you want to count the number of documents in a collection, e.g. count({}), use the estimatedDocumentCount() function instead. Otherwise, use the countDocuments() function instead.

Model.estimatedDocumentCount() Estimates the number of documents in the MongoDB collection. It is Faster than using countDocuments() for large collections because estimatedDocumentCount() uses collection metadata rather than scanning the entire collection.

Example:

const numAdventures = await Adventure.estimatedDocumentCount();

reference : https://mongoosejs.com/docs/api.html#model_Model.estimatedDocumentCount

Upvotes: 4

Mridul Tripathi
Mridul Tripathi

Reputation: 839

The highest voted answers here are perfectly fine I just want to add up the use of await so that the functionality asked for can be achieved:

const documentCount = await userModel.count({});
console.log( "Number of users:", documentCount );

It's recommended to use countDocuments() over 'count()' as it will be deprecated going on. So, for now, the perfect code would be:

const documentCount = await userModel.countDocuments({});
console.log( "Number of users:", documentCount );

Upvotes: 4

Andressa Pinheiro
Andressa Pinheiro

Reputation: 1637

As said before, your code will not work the way it is. A solution to that would be using a callback function, but if you think it would carry you to a 'Callback hell', you can search for "Promisses".

A possible solution using a callback function:

//DECLARE  numberofDocs OUT OF FUNCTIONS
     var  numberofDocs;
     userModel.count({}, setNumberofDocuments); //this search all DOcuments in a Collection

if you want to search the number of documents based on a query, you can do this:

 userModel.count({yourQueryGoesHere}, setNumberofDocuments);

setNumberofDocuments is a separeted function :

var setNumberofDocuments = function(err, count){ 
        if(err) return handleError(err);

        numberofDocs = count;

      };

Now you can get the number of Documents anywhere with a getFunction:

     function getNumberofDocs(){
           return numberofDocs;
        }
 var number = getNumberofDocs();

In addition , you use this asynchronous function inside a synchronous one by using a callback, example:

function calculateNumberOfDoc(someParameter, setNumberofDocuments){

       userModel.count({}, setNumberofDocuments); //this search all DOcuments in a Collection

       setNumberofDocuments(true);


} 

Upvotes: -1

Moh .S
Moh .S

Reputation: 2090

You should give an object as argument

userModel.countDocuments({name: "sam"});

or

userModel.countDocuments({name: "sam"}).exec(); //if you are using promise

or

userModel.countDocuments({}); // if you want to get all counts irrespective of the fields

For the older versions of mongoose, use

userModel.count({name: "sam"});

Upvotes: 52

Abid
Abid

Reputation: 361

Using mongoose.js you can count documents,

  • count all
const count = await Schema.countDocuments();
  • count specific
const count = await Schema.countDocuments({ key: value });

Upvotes: 9

heilala
heilala

Reputation: 856

Background for the solution

As stated in the mongoose documentation and in the answer by Benjamin, the method Model.count() is deprecated. Instead of using count(), the alternatives are the following:

Model.countDocuments(filterObject, callback)

Counts how many documents match the filter in a collection. Passing an empty object {} as filter executes a full collection scan. If the collection is large, the following method might be used.

Model.estimatedDocumentCount()

This model method estimates the number of documents in the MongoDB collection. This method is faster than the previous countDocuments(), because it uses collection metadata instead of going through the entire collection. However, as the method name suggests, and depending on db configuration, the result is an estimate as the metadata might not reflect the actual count of documents in a collection at the method execution moment.

Both methods return a mongoose query object, which can be executed in one of the following two ways. Use .exec() if you want to execute a query at a later time.

The solution

Option 1: Pass a callback function

For example, count all documents in a collection using .countDocuments():

someModel.countDocuments({}, function(err, docCount) {
    if (err) { return handleError(err) } //handle possible errors
    console.log(docCount)
    //and do some other fancy stuff
})

Or, count all documents in a collection having a certain name using .countDocuments():

someModel.countDocuments({ name: 'Snow' }, function(err, docCount) {
    //see other example
}

Option 2: Use .then()

A mongoose query has .then() so it’s “thenable”. This is for a convenience and query itself is not a promise.

For example, count all documents in a collection using .estimatedDocumentCount():

someModel
    .estimatedDocumentCount()
    .then(docCount => {
        console.log(docCount)
        //and do one super neat trick
    })
    .catch(err => {
        //handle possible errors
    })

Option 3: Use async/await

When using async/await approach, the recommended way is to use it with .exec() as it provides better stack traces.

const docCount = await someModel.countDocuments({}).exec();

Learning by stackoverflowing,

Upvotes: 25

patalmypal
patalmypal

Reputation: 6712

The code below works. Note the use of countDocuments.

 var mongoose = require('mongoose');
 var db = mongoose.connect('mongodb://localhost/myApp');
 var userSchema = new mongoose.Schema({name:String,password:String});
 var userModel =db.model('userlists',userSchema);
 var anand = new userModel({ name: 'anand', password: 'abcd'});
 anand.save(function (err, docs) {
   if (err) {
       console.log('Error');
   } else {
       userModel.countDocuments({name: 'anand'}, function(err, c) {
           console.log('Count is ' + c);
      });
   }
 }); 

Upvotes: 168

Benjamin
Benjamin

Reputation: 573

The collection.count is deprecated, and will be removed in a future version. Use collection.countDocuments or collection.estimatedDocumentCount instead.

userModel.countDocuments(query).exec((err, count) => {
    if (err) {
        res.send(err);
        return;
    }

    res.json({ count: count });
});

Upvotes: 33

UpTheCreek
UpTheCreek

Reputation: 32391

The reason your code doesn't work is because the count function is asynchronous, it doesn't synchronously return a value.

Here's an example of usage:

userModel.count({}, function( err, count){
    console.log( "Number of users:", count );
})

Upvotes: 174

Related Questions