Mongoose: Count Documents in a Collection (with examples)

Updated: December 30, 2023 By: Guest Contributor Post a comment

This practical article will walk you through some different ways to count documents in a collection by using Mongoose.

Solution 1: Model.countDocuments()

Use the countDocuments() function provided by Mongoose model for counting documents. This is the most straight-forward approach and works well for simple use cases.

Here’s the (boring) steps to follow:

  • Start by ensuring that you have a Mongoose model for the collection you want to count documents in.
  • Next, call the countDocuments() function on the model. You can optionally pass a query object to count only the documents that match the query.
  • Finally, handle the promise returned by countDocuments() using then() or by using async/await in an async function.

Example:

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_database');
const MyModel = mongoose.model('MyModel', new mongoose.Schema({ /* schema definition */ }));

async function countDocs(query = {}) {
  try {
    const count = await MyModel.countDocuments(query);
    console.log('Document count:', count);
  } catch (error) {
    console.error('Error counting documents:', error);
  }
}

countDocs(); // Call the function to count all documents

Pros: Easy to use; Supports query object for filtered counts.

Cons: Can be slow for large collections; Doesn’t use indexes.

Solution 2: Model.aggregate() with Count

Employ the aggregate() function along with a count operation. This solution can be optimized to use indexes.

Summary:

  • Define your aggregation pipeline, making sure to include the $count stage at the end.
  • Execute the aggregate() function with your defined pipeline.
  • Process the result, which will include the count.

A small example:

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_database');
const MyModel = mongoose.model('MyModel', new mongoose.Schema({ /* schema definition */ }));

async function aggregateCount() {
  try {
    const result = await MyModel.aggregate([ { $count: 'totalDocuments' } ]);
    console.log('Document count:', result[0].totalDocuments);
  } catch (error) {
    console.error('Error with aggregate count:', error);
  }
}

aggregateCount(); // Call the function to count all documents

Pros: Can be faster and use indexes; Flexible with complex queries.

Cons: More complex syntax; Overhead of aggregation pipeline.

Solution 3: Model.estimatedDocumentCount()

The estimatedDocumentCount() function returns an estimation of the count of documents in a collection. It’s faster but potentially less accurate.

The process is as follows:

  • Simply call the estimatedDocumentCount() function on the model you wish to count documents in.
  • Handle the returned promise using then() or within an async function.

Example:

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_database');
const MyModel = mongoose.model('MyModel', new mongoose.Schema({ /* schema definition */ }));

async function estimateDocCount() {
  try {
    const count = await MyModel.estimatedDocumentCount();
    console.log('Estimated document count:', count);
  } catch (error) {
    console.error('Error estimating document count:', error);
  }
}

estimateDocCount(); // Call the function

Pros: Very fast; No need for a collection scan.

Cons: Not accurate if there are ongoing write operations; Doesn’t support queries.

Conclusion

Counting documents in Mongoose can be done through several methods, each with its own use cases and limitations. The simplest method countDocuments() works well for small to medium collections. The aggregate() method provides more flexibility and can be optimized with indexes, and is preferable for complex queries. For a fast estimation, estimatedDocumentCount() is the go-to. Picking the right count method depends on your specific application needs like accuracy, performance, and query complexity.