HOWTO · MongoDB

Datensätze in MongoDB zählen

Erfahren Sie, wie Sie alle oder gefilterte MongoDB-Dokumente zählen, Zählungen gruppieren und sortieren, Dokumente nach Datum zählen und mit Cursor-Ergebnissen arbeiten.

Auf dieser Seite

Um in MongoDB Dokumente zu zählen, die einem Filter entsprechen, verwenden Sie db.collection.countDocuments(filter) in mongosh oder setzen Sie in einer Aggregationspipeline $match vor $count. Mit db.collection.countDocuments({}) zählen Sie alle Dokumente. Eine Aggregation ist nützlich, wenn die Zählung Teil einer größeren Abfrage ist, etwa beim Gruppieren von Dokumenten nach einem Feld oder Datum.

Führen Sie dieses Beispiel aus:

scores = [88, 92, 97, 71, 79, 83]
passing = [score for score in scores if score > 80]
print(len(passing))
4

Diese lokale Python-Veranschaulichung wendet denselben Filter auf eine kleine Liste an; sie stellt keine Verbindung zu MongoDB her. Die MongoDB-Variante finden Sie weiter unten im Abschnitt zur Aggregation.

MongoDB-Operationen

MongoDB speichert Daten als Dokumente in Collections. Für Zählungen ist ein Lesevorgang relevant: Wählen Sie eine Collection aus, wenden Sie optional einen Filter an und geben Sie entweder eine Anzahl oder gruppierte Ergebnisse zurück. Die Beispiele verwenden scores für Prüfungsergebnisse und sales für datierte Transaktionen. Ersetzen Sie diese Namen für Collections und Felder durch die in Ihrer Datenbank verwendeten Namen.

MongoDB-Aggregation

Eine Aggregationspipeline leitet Dokumente durch geordnete Stufen. Jede Stufe kann die Dokumente, die sie erreicht haben, filtern, gruppieren, berechnen oder sortieren. Zum Beispiel filtert aggregate([{ $match: { status: "paid" } }, { $group: { _id: "$customerId", orders: { $sum: 1 } } }]) bezahlte Bestellungen und zählt sie anschließend pro Kunde. Der Code zeigt die MongoDB-Shell-Syntax; zur Ausführung benötigen Sie einen MongoDB-Server oder eine Shell.

$count in MongoDB

Die Stufe $count zählt die Dokumente, die sie erreichen, und gibt ein Dokument zurück, dessen Feldname die an $count übergebene Zeichenfolge ist. Setzen Sie $match davor, wenn nur Dokumente gezählt werden sollen, die eine Bedingung erfüllen. Für die sechs oben gezeigten Prüfungsergebnisse lautet die entsprechende Pipeline db.scores.aggregate([{ $match: { score: { $gt: 80 } } }, { $count: "passing_scores" }]). Das Ergebnisdokument hat die Form { "passing_scores": 4 }. passing_scores ist ein Ausgabefeld, keine Variable.

Erreichen keine Dokumente diese Stufe, gibt $count kein Ergebnisdokument zurück. Wenn das Ergebnis immer eine numerische Null enthalten soll, behandeln Sie diesen Fall in der Anwendung oder passen Sie die Pipeline entsprechend an. Eine Pipeline-Zählung lässt sich auch mit $group ausdrücken, indem pro Eingabedokument eins addiert wird: [{ $group: { _id: null, myCount: { $sum: 1 } } }, { $project: { _id: 0, myCount: 1 } }]. Die Projektion behält das Zählfeld bei und entfernt _id.

db.collection.count() in MongoDB

In mongosh gibt db.collection.count() eine Anzahl zurück; db.collection.count(query) wendet zusätzlich einen Abfragefilter an. Zum Beispiel zählt db.orders.count({ status: "paid" }) die passenden Bestellungen. MongoDB hat diese Methode in Version 4.0 als veraltet eingestuft. Die aktuelle Dokumentation empfiehlt countDocuments() für eine genaue gefilterte Zählung und estimatedDocumentCount(), wenn eine schnelle Metadatenschätzung für die gesamte Collection ausreicht. db.collection.count() kann nicht in einer Transaktion verwendet werden; nutzen Sie dort stattdessen countDocuments(). Die Methodennamen können je nach Treiber abweichen. Prüfen Sie daher die Dokumentation des in Ihrer Anwendung verwendeten Treibers. Verwenden Sie aggregate(), wenn die Zählung mit Pipeline-Stufen kombiniert oder zusammen mit gruppierten Werten zurückgegeben werden soll. Siehe die MongoDB-Referenzen zu count() und countDocuments().

Sharded-Cluster

Laut MongoDB kann count() in einem Sharded-Cluster ein ungenaues Ergebnis liefern, wenn verwaiste Dokumente vorhanden sind oder gerade eine Chunk-Migration läuft. Verwenden Sie für eine Abfragezählung countDocuments(). Die count()-Dokumentation erläutert den Vorbehalt; die Dokumentation zu countDocuments() nennt die empfohlene Alternative. Diese Aussagen beruhen auf dem aktuellen Handbuch. Prüfen Sie die Dokumentation für Ihre Serverversion.

Indexverwendung

Ob ein Index bei einem Zählfilter hilft, hängt von der Abfrage, den verfügbaren Indizes und dem gewählten Ausführungsplan ab. Untersuchen Sie den tatsächlichen Vorgang mit explain() und beachten Sie die Hinweise zur Abfrageoptimierung von MongoDB. Ein Index garantiert nicht, dass sich eine Zählung allein anhand der Indexschlüssel beantworten lässt.

Genauigkeit nach einem unerwarteten Herunterfahren

MongoDB weist darauf hin, dass count() nach einem nicht ordnungsgemäßen Herunterfahren ungenaue Ergebnisse liefern kann, weil die Methode auf Metadaten der Collection zurückgreifen kann. Wenn Sie die Anzahl der Dokumente benötigen, die einem Filter entsprechen, verwenden Sie countDocuments(), um diese Dokumente zu zählen. validate prüft Daten und Indizes einer Collection und dient der Diagnose; es ersetzt keine Zählabfrage. Beachten Sie den Vorbehalt zu count() und die versionsspezifischen Hinweise zum Befehl validate, bevor Sie Wiederherstellungsmaßnahmen ergreifen.

Verbindung zum Client getrennt

Wird die Verbindung unterbrochen, bevor eine Zählantwort den Client erreicht, liegt dem Client keine zurückgegebene Anzahl zur Prüfung vor. Behandeln Sie den daraus entstehenden Fehler gemäß der Dokumentation des verwendeten Treibers. Eine ausbleibende Antwort ist keine bestätigte Zählung. Die Treiberdokumentation von MongoDB beschreibt treiberspezifisches Verhalten und API-Details.

Alle Dokumente einer Collection zählen

Um mit der Aggregationsstufe jedes Dokument in orders zu zählen, verwenden Sie db.orders.aggregate([{ $count: "total" }]). Für eine numerische Anzahl in einer Anwendung verwenden Sie die Zähl-API des MongoDB-Treibers für die jeweilige Sprache. In mongosh macht db.orders.countDocuments({}) den Filter für alle Dokumente ausdrücklich sichtbar.

Alle Dokumente zählen, die einer Abfrage entsprechen

Übergeben Sie einen Filter, um nur passende Dokumente zu zählen. Zum Beispiel zählt db.orders.countDocuments({ orderDate: { $gte: ISODate("2024-01-01T00:00:00Z"), $lt: ISODate("2025-01-01T00:00:00Z") } }) Bestellungen aus dem UTC-Jahr 2024. Die untere Grenze ist eingeschlossen, die obere ausgeschlossen. Ein Zeitstempel am Anfang des Jahres 2025 wird daher nicht mitgezählt.

Dokumente in MongoDB gruppieren und zählen

Die folgenden Dokumente in students veranschaulichen die Beispiele: { name: "Ava", city: "Paris", courses: ["math", "science"] }, { name: "Ben", city: "Paris", courses: ["math"] } und { name: "Cam", city: "Lyon", courses: ["science", "history"] }. Dies sind beispielhafte Eingabedokumente; die MongoDB-Shell-Pipelines unten werden nicht durch das lokale Python-Beispiel dieses Artikels ausgeführt.

Verwenden Sie $group mit $sum: 1, um Dokumente für jeden unterschiedlichen Wert eines Felds zu zählen. db.students.aggregate([{ $group: { _id: "$city", students: { $sum: 1 } } }]) gibt { "_id": "Paris", "students": 2 } und { "_id": "Lyon", "students": 1 } zurück. Ein konstanter Gruppenschlüssel wie _id: null erstellt eine einzige Gruppe für die gesamte Eingabe; die Dokumente werden dadurch nicht nach einem Feld gruppiert.

Gruppierte Anzahlen in MongoDB sortieren

$sortByCount gruppiert Dokumente anhand eines Ausdrucks, zählt jede Gruppe und sortiert die Ergebnisse absteigend nach Anzahl. Für die beispielhaften courses-Arrays gibt db.students.aggregate([{ $unwind: "$courses" }, { $sortByCount: "$courses" }]) zunächst pro Array-Element ein Pipeline-Dokument aus. Die erwarteten Ergebnisse sind { "_id": "math", "count": 2 }, { "_id": "science", "count": 2 } und { "_id": "history", "count": 1 } (die beiden gleich großen Gruppen können in beliebiger Reihenfolge erscheinen). Durch $unwind wird jedes Array-Element einzeln berücksichtigt. Die entsprechenden expliziten Stufen lauten [{ $unwind: "$courses" }, { $group: { _id: "$courses", count: { $sum: 1 } } }, { $sort: { count: -1 } }].

In MongoDB nach mehreren Feldern gruppieren und zählen

Fügen Sie jedes Gruppierungsfeld in das _id-Dokument ein, um jede unterschiedliche Kombination zu zählen. Bei den folgenden Anfragedokumenten { source: "web", status: "ok" }, { source: "web", status: "error" } und { source: "web", status: "ok" } gibt db.requests.aggregate([{ $group: { _id: { source: "$source", status: "$status" }, requests: { $sum: 1 } } }, { $sort: { "_id.source": 1, "_id.status": 1 } }]) { "_id": { "source": "web", "status": "error" }, "requests": 1 } und { "_id": { "source": "web", "status": "ok" }, "requests": 2 } zurück. $count zählt die Pipeline-Dokumente, die diese Stufe erreichen; für Zählungen innerhalb von Gruppen ist $group mit $sum: 1 das passende Muster.

In MongoDB nach Datum gruppieren und zählen

Um tägliche Bestellzahlen und Umsätze zu berechnen, gruppieren Sie nach einem Datum im Format Jahr, Monat und Tag. Die folgenden Dokumente in sales verwenden UTC-Daten sowie numerische Felder price und quantity: { date: ISODate("2024-03-01T12:00:00Z"), price: 10, quantity: 2 }, { date: ISODate("2024-03-01T18:00:00Z"), price: 5, quantity: 1 } und { date: ISODate("2024-04-02T09:00:00Z"), price: 7, quantity: 3 }. Der halboffene Zeitraum umfasst März und April 2024 und schließt den 1. Mai 2024 aus.

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 } }]).

Für diese Dokumente lauten die erwarteten Ergebnisse { "_id": "2024-03-01", "totalSales": 25, "orderCount": 2 } und { "_id": "2024-04-02", "totalSales": 21, "orderCount": 1 }. Jede Summe entspricht der Summe von price * quantity für den jeweiligen UTC-Tag. Wenn Ihre gespeicherten Daten oder Ihr Geschäftstag eine andere Zeitzone verwenden, legen Sie die Bereichsgrenzen und die Gruppierungszeitzone einheitlich fest. Die Abfrage verwendet MongoDB-Shell-Syntax und benötigt eine Datenbank mit den beschriebenen Feldern. Das Ergebnis wurde aus den Beispieldokumenten oben abgeleitet und beruht nicht auf Laufzeitnachweisen.

Einen Cursor mit toArray() in ein Array umwandeln

toArray() liest die verbleibenden Cursor-Ergebnisse und gibt sie als Array zurück. Das ist praktisch, wenn die Anwendung die Ergebnisse mehrfach indizieren oder durchlaufen muss; dabei belegen alle Dokumente gemeinsam Arbeitsspeicher in der Anwendung. Bei großen Ergebnismengen sollten Sie den Cursor durchlaufen, statt alle Dokumente auf einmal in ein Array zu laden. In mongosh gibt db.products.find({ active: true }).toArray() ein Array passender Produktdokumente zurück; es ist keine Zähloperation.

Verbleibende Dokumente in einem Cursor mit itcount() zählen

In mongosh zählt itcount() die verbleibenden Dokumente eines Cursors, indem die Ergebnisse verbraucht werden. Das ist hilfreich, um einen Cursor in einer interaktiven Shell zu untersuchen; anschließend ist der Cursor jedoch erschöpft. Die Methode ist keine wiederverwendbare Zählabfrage und ersetzt countDocuments() nicht, wenn die Anwendung eine Anzahl benötigt, ohne einen Cursor zu verbrauchen, den sie weiterverwenden möchte.