HOWTO · MongoDB
Contar registros en MongoDB
Aprende a contar todos los documentos de MongoDB o solo los que coinciden con un filtro, agrupar y ordenar los recuentos, contar por fecha y trabajar con los resultados de un cursor.
En esta página
Para contar en MongoDB los documentos que coinciden con un filtro, usa db.collection.countDocuments(filter) en mongosh o coloca $match antes de $count en una canalización de agregación. Para contar todos los documentos, usa db.collection.countDocuments({}). La agregación resulta útil cuando el recuento forma parte de una consulta más amplia, por ejemplo, al agrupar documentos por un campo o por fecha.
Ejecuta este ejemplo:
scores = [88, 92, 97, 71, 79, 83]
passing = [score for score in scores if score > 80]
print(len(passing))
4
Esta demostración local en Python aplica el mismo filtro a una lista pequeña; no se conecta a MongoDB. La versión para MongoDB aparece más abajo, en la sección sobre agregación.
Operaciones en MongoDB
MongoDB almacena datos en documentos agrupados en colecciones. Para contar, la operación pertinente es una lectura: selecciona una colección, aplica un filtro si lo necesitas y devuelve un recuento o resultados agrupados. En los ejemplos se usa scores para resultados de exámenes y sales para transacciones con fecha. Sustituye esos nombres de colecciones y campos por los de tu base de datos.
Agregación en MongoDB
Una canalización de agregación procesa documentos mediante etapas ordenadas. Cada etapa puede filtrar, agrupar, calcular u ordenar los documentos que recibe. Por ejemplo, aggregate([{ $match: { status: "paid" } }, { $group: { _id: "$customerId", orders: { $sum: 1 } } }]) filtra los pedidos pagados y después los cuenta por cliente. El código muestra la sintaxis del shell de MongoDB; para ejecutarlo se necesita un servidor o un shell de MongoDB.
$count en MongoDB
La etapa $count cuenta los documentos que llegan hasta ella y emite un documento cuyo nombre de campo es la cadena indicada en $count. Coloca $match antes para contar solo los documentos que cumplen una condición. Con las seis puntuaciones mostradas arriba, la canalización equivalente es db.scores.aggregate([{ $match: { score: { $gt: 80 } } }, { $count: "passing_scores" }]). El documento resultante tiene la forma { "passing_scores": 4 }. passing_scores es un campo de salida, no una variable.
$count no genera ningún documento de resultado cuando no llega ningún documento a esa etapa. Si necesitas que el resultado siempre incluya un cero numérico, gestiona ese caso en la aplicación o adapta la canalización. Otra forma de expresar un recuento en una canalización es usar $group para sumar uno por cada documento de entrada: [{ $group: { _id: null, myCount: { $sum: 1 } } }, { $project: { _id: 0, myCount: 1 } }]. La proyección conserva el campo del recuento y elimina _id.
db.collection.count() en MongoDB
En mongosh, db.collection.count() devuelve un recuento y db.collection.count(query) aplica un filtro de consulta. Por ejemplo, db.orders.count({ status: "paid" }) cuenta los pedidos que coinciden. MongoDB dejó obsoleto este método en la versión 4.0; la documentación actual recomienda countDocuments() para obtener un recuento preciso con filtro y estimatedDocumentCount() cuando basta con una estimación rápida de los metadatos de toda la colección. db.collection.count() no se puede usar en una transacción; en ese caso, utiliza countDocuments(). Los nombres de los métodos pueden variar entre controladores, así que consulta la documentación del controlador que use tu aplicación. Usa aggregate() cuando necesites combinar el recuento con etapas de una canalización o devolverlo junto con valores agrupados. Consulta las referencias de MongoDB para count() y countDocuments().
Clústeres fragmentados
MongoDB documenta que count() puede devolver un resultado impreciso en un clúster fragmentado si hay documentos huérfanos o si se está migrando un fragmento. Para contar documentos que coincidan con una consulta, usa countDocuments(); consulta la documentación de count() para conocer la salvedad y la documentación de countDocuments() para ver la alternativa recomendada. Estas indicaciones corresponden al manual actual; consulta la documentación de la versión de tu servidor.
Uso de índices
Que un índice ayude a filtrar un recuento depende de la consulta, los índices disponibles y el plan seleccionado. Examina la operación concreta con explain() y consulta las recomendaciones de optimización de consultas de MongoDB; un índice no garantiza que el recuento pueda obtenerse únicamente de las claves del índice.
Precisión tras un apagado inesperado
MongoDB indica que count() puede devolver resultados imprecisos después de un apagado no limpio, porque puede basarse en los metadatos de la colección. Si necesitas contar los documentos que coinciden con un filtro, usa countDocuments() para contar los documentos que lo cumplen. validate comprueba los datos y los índices de la colección; es una herramienta de diagnóstico, no sustituye a una consulta de recuento. Antes de tomar medidas de recuperación, consulta la salvedad de count() y la documentación del comando validate correspondiente a tu versión.
Desconexión del cliente
Si la conexión se cierra antes de que el cliente reciba la respuesta del recuento, el cliente no tiene ningún valor devuelto que consultar. Gestiona el error según las indicaciones del controlador utilizado; no interpretes la falta de respuesta como un recuento confirmado. La documentación de controladores de MongoDB describe el comportamiento y las API específicos de cada controlador.
Contar todos los documentos de una colección
Para contar todos los documentos de orders con la etapa de agregación, usa db.orders.aggregate([{ $count: "total" }]). Para obtener un recuento numérico desde una aplicación, usa la API de recuento del controlador de MongoDB para ese lenguaje. En mongosh, db.orders.countDocuments({}) hace explícito el filtro que incluye todos los documentos.
Contar todos los documentos que coinciden con una consulta
Pasa un filtro para contar solo los documentos que coinciden. Por ejemplo, db.orders.countDocuments({ orderDate: { $gte: ISODate("2024-01-01T00:00:00Z"), $lt: ISODate("2025-01-01T00:00:00Z") } }) cuenta los pedidos del año 2024 en UTC. El límite inferior está incluido y el superior está excluido, así que no se incluye una marca de tiempo al comienzo de 2025.
Agrupar y contar documentos en MongoDB
Los siguientes documentos de students sirven para ilustrar los ejemplos: { name: "Ava", city: "Paris", courses: ["math", "science"] }, { name: "Ben", city: "Paris", courses: ["math"] } y { name: "Cam", city: "Lyon", courses: ["science", "history"] }. Son documentos de entrada ilustrativos; las canalizaciones del shell de MongoDB que aparecen a continuación no se ejecutan mediante el ejemplo local en Python de este artículo.
Usa $group con $sum: 1 para contar los documentos de cada valor distinto de un campo. db.students.aggregate([{ $group: { _id: "$city", students: { $sum: 1 } } }]) devuelve { "_id": "Paris", "students": 2 } y { "_id": "Lyon", "students": 1 }. Una clave de agrupación constante, como _id: null, crea un único grupo con toda la entrada; no agrupa los documentos por el valor de un campo.
Ordenar recuentos agrupados en MongoDB
$sortByCount agrupa los documentos según una expresión, cuenta cada grupo y ordena los resultados por recuento en orden descendente. Con los arreglos de courses del ejemplo, db.students.aggregate([{ $unwind: "$courses" }, { $sortByCount: "$courses" }]) primero genera un documento de canalización por cada elemento del arreglo. Los resultados esperados son { "_id": "math", "count": 2 }, { "_id": "science", "count": 2 } y { "_id": "history", "count": 1 } (los dos grupos empatados pueden aparecer en cualquier orden). $unwind hace que cada elemento del arreglo cuente por separado. Las etapas explícitas equivalentes son [{ $unwind: "$courses" }, { $group: { _id: "$courses", count: { $sum: 1 } } }, { $sort: { count: -1 } }].
Agrupar y contar por varios campos en MongoDB
Incluye cada campo de agrupación en el documento _id para contar cada combinación distinta. Por ejemplo, dados los documentos de solicitudes { source: "web", status: "ok" }, { source: "web", status: "error" } y { source: "web", status: "ok" }, db.requests.aggregate([{ $group: { _id: { source: "$source", status: "$status" }, requests: { $sum: 1 } } }, { $sort: { "_id.source": 1, "_id.status": 1 } }]) devuelve { "_id": { "source": "web", "status": "error" }, "requests": 1 } y { "_id": { "source": "web", "status": "ok" }, "requests": 2 }. $count cuenta los documentos de la canalización que llegan hasta esa etapa; para contar dentro de grupos, se usa $group con $sum: 1.
Agrupar y contar por fecha en MongoDB
Para calcular recuentos diarios de pedidos y totales de ventas, agrupa por una fecha con formato de año, mes y día. Estos documentos de sales usan fechas UTC y campos numéricos price y quantity: { date: ISODate("2024-03-01T12:00:00Z"), price: 10, quantity: 2 }, { date: ISODate("2024-03-01T18:00:00Z"), price: 5, quantity: 1 } y { date: ISODate("2024-04-02T09:00:00Z"), price: 7, quantity: 3 }. El intervalo semiabierto incluye marzo y abril de 2024 y excluye el 1 de mayo de 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 } }]).
Para esos documentos, los resultados esperados son { "_id": "2024-03-01", "totalSales": 25, "orderCount": 2 } y { "_id": "2024-04-02", "totalSales": 21, "orderCount": 1 }. Cada total suma price * quantity de ese día en UTC. Si las fechas almacenadas o el día comercial usan otra zona horaria, configura de forma coherente los límites del intervalo y la zona horaria de agrupación. La consulta usa la sintaxis del shell de MongoDB y requiere una base de datos que contenga los campos descritos; el resultado se deduce de los documentos de ejemplo anteriores, no de pruebas en tiempo de ejecución.
Convertir un cursor en una matriz con toArray()
toArray() lee los resultados restantes del cursor y los devuelve en una matriz. Es práctico cuando la aplicación necesita acceder a los resultados por índice o recorrerlos más de una vez, pero todos los documentos ocupan memoria de la aplicación al mismo tiempo. Para conjuntos grandes, recorre el cursor en vez de cargar todos los documentos a la vez. En mongosh, db.products.find({ active: true }).toArray() devuelve una matriz con los documentos de producto que coinciden; no es una operación de recuento.
Contar los documentos restantes de un cursor con itcount()
En mongosh, itcount() cuenta los documentos que quedan en un cursor consumiendo esos resultados. Es útil para inspeccionar un cursor en un shell interactivo, pero después el cursor queda agotado. No es una consulta de recuento reutilizable ni sustituye a countDocuments() cuando la aplicación necesita obtener un recuento sin consumir un cursor que todavía piensa usar.