HOWTO · MongoDB
How to Count Documents in MongoDB
Learn how to count all or filtered MongoDB documents, group and sort counts, count by date, and work with cursor results.
On this page
To count documents that match a filter in MongoDB, use db.collection.countDocuments(filter) in mongosh, or put $match before $count in an aggregation pipeline. Use db.collection.countDocuments({}) for all documents. Aggregation is useful when the count is one step in a larger query, such as grouping documents by a field or date.
Run this example:
scores = [88, 92, 97, 71, 79, 83]
passing = [score for score in scores if score > 80]
print(len(passing))
4
This local Python illustration applies the same filter to a small list; it does not connect to MongoDB. The MongoDB version appears in the aggregation section below.
MongoDB operations
MongoDB stores data as documents inside collections. For counting tasks, the relevant operation is a read: select a collection, optionally apply a filter, and return either a count or grouped results. The examples use scores for exam results and sales for dated transactions. Replace those collection and field names with the ones in your database.
MongoDB aggregation
An aggregation pipeline passes documents through ordered stages. Each stage can filter, group, calculate, or sort the documents that reach it. For example, aggregate([{ $match: { status: "paid" } }, { $group: { _id: "$customerId", orders: { $sum: 1 } } }]) filters paid orders and then counts them per customer. The code here shows MongoDB shell syntax; a MongoDB server or shell is required to execute it.
$count in MongoDB
The $count stage counts documents that reach it and emits a document whose field name is the string supplied to $count. Place $match before it to count only documents meeting a condition. With the six scores shown above, the equivalent pipeline is db.scores.aggregate([{ $match: { score: { $gt: 80 } } }, { $count: "passing_scores" }]). Its result document has the shape { "passing_scores": 4 }. passing_scores is an output field, not a variable.
$count produces no result document when no documents reach that stage. If the result must always include a numeric zero, handle that case in the application or shape the pipeline accordingly. As another way to express a pipeline count, $group can sum one per input document: [{ $group: { _id: null, myCount: { $sum: 1 } } }, { $project: { _id: 0, myCount: 1 } }]. The projection keeps the count field and removes _id.
db.collection.count() in MongoDB
In mongosh, db.collection.count() returns a count, and db.collection.count(query) applies a query filter. For example, db.orders.count({ status: "paid" }) counts matching orders. MongoDB deprecated this method in version 4.0; its current documentation recommends countDocuments() for an accurate filtered count and estimatedDocumentCount() when a fast metadata estimate of the whole collection is sufficient. db.collection.count() cannot be used in a transaction; use countDocuments() there instead. Driver method names may differ, so check the documentation for the driver used by your application. Use aggregate() when the count must be combined with pipeline stages or returned alongside grouped values. See MongoDB’s count() reference and countDocuments() reference.
Sharded Clusters
MongoDB documents that count() can return an inaccurate result on a sharded cluster when orphaned documents are present or a chunk migration is in progress. For a query count, use countDocuments(); consult the count() documentation for the caveat and the countDocuments() documentation for the recommended alternative. These statements follow the current manual; check the documentation matching your server version.
Index Use
Whether an index helps a count filter depends on the query, available indexes, and selected plan. Inspect the actual operation with explain() and review MongoDB’s query optimization guidance; an index does not guarantee that a count can be answered from index keys alone.
Accuracy in the Event of an Unexpected Shutdown
MongoDB documents that count() can return inaccurate results after an unclean shutdown because it may rely on collection metadata. When you need a count of matching documents, use countDocuments() to count the documents that meet the filter. validate checks collection data and indexes; it is a diagnostic, not a substitute for a count query. Follow the count() caveat and the version-specific validate command guidance before taking recovery action.
Disconnection of Client
If the connection closes before a count response reaches the client, the client has no returned count to inspect. Handle the resulting error according to the selected driver’s guidance; do not treat a missing response as a confirmed count. MongoDB’s driver documentation provides driver-specific behavior and API details.
Count All Documents in a Collection
To count every document in orders with the aggregation stage, use db.orders.aggregate([{ $count: "total" }]). To get a numeric count from an application, use that language’s MongoDB driver count API. In mongosh, db.orders.countDocuments({}) makes the all-documents filter explicit.
Count All Documents that Match a Query
Pass a filter to count only matching documents. For example, db.orders.countDocuments({ orderDate: { $gte: ISODate("2024-01-01T00:00:00Z"), $lt: ISODate("2025-01-01T00:00:00Z") } }) counts orders in the UTC year 2024. The lower bound is inclusive and the upper bound is exclusive, so a timestamp at the start of 2025 is not included.
Group and count documents in MongoDB
The following students documents make the examples concrete: { name: "Ava", city: "Paris", courses: ["math", "science"] }, { name: "Ben", city: "Paris", courses: ["math"] }, and { name: "Cam", city: "Lyon", courses: ["science", "history"] }. These are illustrative input documents; the MongoDB shell pipelines below are not executed by this article’s local Python example.
Use $group with $sum: 1 to count documents for each distinct value of a field. db.students.aggregate([{ $group: { _id: "$city", students: { $sum: 1 } } }]) returns { "_id": "Paris", "students": 2 } and { "_id": "Lyon", "students": 1 }. A constant group key such as _id: null creates one group for the entire input; it does not group documents by a field.
Sort grouped counts in MongoDB
$sortByCount groups documents by an expression, counts each group, and sorts the results by count in descending order. For the sample courses arrays, db.students.aggregate([{ $unwind: "$courses" }, { $sortByCount: "$courses" }]) first emits one pipeline document per array element. Its expected results are { "_id": "math", "count": 2 }, { "_id": "science", "count": 2 }, and { "_id": "history", "count": 1 } (the two tied groups may appear in either order). $unwind makes each array element contribute separately. The equivalent explicit stages are [{ $unwind: "$courses" }, { $group: { _id: "$courses", count: { $sum: 1 } } }, { $sort: { count: -1 } }].
Group and count by multiple fields in MongoDB
Put each grouping field in the _id document to count each distinct combination. For example, given request documents { source: "web", status: "ok" }, { source: "web", status: "error" }, and { source: "web", status: "ok" }, db.requests.aggregate([{ $group: { _id: { source: "$source", status: "$status" }, requests: { $sum: 1 } } }, { $sort: { "_id.source": 1, "_id.status": 1 } }]) returns { "_id": { "source": "web", "status": "error" }, "requests": 1 } and { "_id": { "source": "web", "status": "ok" }, "requests": 2 }. $count counts the pipeline documents that reach it; $group with $sum: 1 is the pattern for counts within groups.
Group and count by date in MongoDB
To calculate daily order counts and sales totals, group by a date formatted as year, month, and day. These sales documents use UTC dates and numeric price and quantity fields: { date: ISODate("2024-03-01T12:00:00Z"), price: 10, quantity: 2 }, { date: ISODate("2024-03-01T18:00:00Z"), price: 5, quantity: 1 }, and { date: ISODate("2024-04-02T09:00:00Z"), price: 7, quantity: 3 }. The half-open range includes March and April 2024 and excludes May 1, 2024.
db.sales.aggregate([{ $match: { date: { $gte: ISODate("2024-03-01T00:00:00Z"), $lt: ISODate("2024-05-01T00:00:00Z") } } }, { $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$date", timezone: "UTC" } }, totalSales: { $sum: { $multiply: ["$price", "$quantity"] } }, orderCount: { $sum: 1 } } }, { $sort: { _id: 1 } }]).
For those documents, the expected results are { "_id": "2024-03-01", "totalSales": 25, "orderCount": 2 } and { "_id": "2024-04-02", "totalSales": 21, "orderCount": 1 }. Each total is the sum of price * quantity for that UTC day. If your stored dates or business day use another timezone, set the range boundaries and grouping timezone consistently. The query is MongoDB shell syntax and requires a database containing the described fields; its result is derived from the sample documents above, not from runtime evidence.
Convert a cursor to an array with toArray()
toArray() reads the remaining cursor results and returns them as an array. This is convenient when the application needs to index or iterate over the result more than once, but the documents occupy application memory together. For large result sets, iterate over the cursor instead of materializing every document at once. In mongosh, db.products.find({ active: true }).toArray() returns an array of matching product documents; it is not a count operation.
Count remaining documents in a cursor with itcount()
In mongosh, itcount() counts documents remaining in a cursor by consuming those results. It is useful for inspecting a cursor in an interactive shell, but the cursor is exhausted afterward. It is not a reusable count query and does not replace countDocuments() when the application needs a count without consuming a cursor it will continue to use.