Mongodb Explain for Aggregation Framework

118

Gibt es eine Erklärungsfunktion für das Aggregationsframework in MongoDB? Ich kann es nicht in der Dokumentation sehen.

Wenn nicht, gibt es eine andere Möglichkeit zu überprüfen, wie eine Abfrage im Aggregationsframework ausgeführt wird.

Ich weiß mit finden Sie einfach zu tun

db.collection.find().explain()

Aber mit dem Aggregationsframework bekomme ich einen Fehler

db.collection.aggregate(
    { $project : { "Tags._id" : 1 }},
    { $unwind : "$Tags" },
    { $match: {$or: [{"Tags._id":"tag1"},{"Tags._id":"tag2"}]}},
    { 
        $group: 
        { 
            _id : { id: "$_id"},
            "count": { $sum:1 } 
        }
    },
    { $sort: {"count":-1}}
).explain()
SCB
quelle

Antworten:

172

Ab MongoDB Version 3.0 ändern Sie einfach die Reihenfolge von

collection.aggregate(...).explain()

zu

collection.explain().aggregate(...)

erhalten Sie die gewünschten Ergebnisse (Dokumentation hier ).

Für ältere Versionen> = 2.6 müssen Sie die explainOption für Aggregationspipeline-Operationen verwenden

explain:true

db.collection.aggregate([
    { $project : { "Tags._id" : 1 }},
    { $unwind : "$Tags" },
    { $match: {$or: [{"Tags._id":"tag1"},{"Tags._id":"tag2"}]}},
    { $group: { 
        _id : "$_id",
        count: { $sum:1 } 
    }},
    {$sort: {"count":-1}}
  ],
  {
    explain:true
  }
)

Eine wichtige Überlegung bei der Aggregation Framework ist , dass ein Index kann nur die Ausgangsdaten für eine Rohrleitung (zB Verwendung von holen verwendet werden $match, $sort, $geonearam Anfang einer Rohrleitung) sowie anschließende $lookupund $graphLookupStufen. Sobald die Daten zur Verarbeitung abgerufen in die Aggregations Pipeline wurden (zB der durch Stufen wie $project, $unwind, und $group) weitere Manipulation in-Speicher sein (möglicherweise unter Verwendung von temporären Dateien , wenn die allowDiskUseOption gesetzt ist).

Pipelines optimieren

Im Allgemeinen können Sie Aggregations-Pipelines optimieren, indem Sie:

  • Starten einer Pipeline mit einer $matchPhase, um die Verarbeitung auf relevante Dokumente zu beschränken.
  • Sicherstellen, dass die Anfangs- $match/ $sortPhasen durch einen effizienten Index unterstützt werden .
  • Filtern von Daten früh mit $match, $limitund $skip.
  • Minimierung unnötiger Phasen und Manipulation von Dokumenten (möglicherweise Überdenken Ihres Schemas, wenn komplizierte Aggregationsgymnastik erforderlich ist).
  • Nutzen Sie neuere Aggregationsoperatoren, wenn Sie Ihren MongoDB-Server aktualisiert haben. In MongoDB 3.4 wurden beispielsweise viele neue Aggregationsstufen und Ausdrücke hinzugefügt, einschließlich der Unterstützung für die Arbeit mit Arrays, Zeichenfolgen und Facetten.

Es gibt auch eine Reihe von Aggregationspipeline-Optimierungen , die abhängig von Ihrer MongoDB-Serverversion automatisch durchgeführt werden. Beispielsweise können benachbarte Stufen zusammengeführt und / oder neu angeordnet werden, um die Ausführung zu verbessern, ohne die Ausgabeergebnisse zu beeinflussen.

Einschränkungen

Wie in MongoDB 3.4 bietet die explainOption Aggregation Framework Informationen zur Verarbeitung einer Pipeline, unterstützt jedoch nicht den gleichen Detaillierungsgrad wie der executionStatsModus für eine find()Abfrage. Wenn Sie sich auf die Optimierung der anfänglichen Abfrageausführung konzentrieren, wird es wahrscheinlich von Vorteil sein, die entsprechende find().explain()Abfrage mit executionStatsoder allPlansExecutionAusführlichkeit zu überprüfen .

Im MongoDB Issue Tracker gibt es einige relevante Feature-Anfragen, die im Hinblick auf detailliertere Ausführungsstatistiken zur Optimierung / Profilaggregation von Pipelines überwacht / verbessert werden müssen:

Stennie
quelle
Vielen Dank für die Info wird sehen, ob ich irgendwelche Änderungen vornehmen kann.
SCB
Sollte sich das $sortObjekt nicht innerhalb des Pipeline-Arrays befinden?
JohnnyHK
@ JohnnyHK: Ja. Einige nette Leute "korrigieren" die Antwort falsch :).
Stennie
Aber dies gibt nicht die "Ausführungsstatistiken"
Kanagavelu Sugumar
1
@KanagaveluSugumar Ich habe die Antwort mit Erläuterungen zu den explainEinschränkungen des Aggregation Frameworks sowie relevanten Funktionsanforderungen für zusätzliche Ausführungsstatistiken aktualisiert .
Stennie
29

Ab Version 2.6.x ermöglicht mongodb Benutzern das Erklären mit dem Aggregationsframework .

Alles was Sie tun müssen, ist EXPLAIN hinzuzufügen: true

db.records.aggregate(
  [ ...your pipeline...],
  { explain: true }
)

Dank Rafa weiß ich, dass es sogar in 2.4 möglich war, aber nur durch runCommand(). Jetzt können Sie aber auch Aggregate verwenden.

Salvador Dali
quelle
5
Tatsächlich können Sie Aggregate mit db.collection.runCommand('aggregate', {pipeline: [PIPELINE], explain: true})seit MongoDB 2.2 erklären .
Rafa
1
Sie haben Recht, in 2.2 und 2.4 können Sie Aggregate nur über runCommand erklären. Danke für die positive Abstimmung.
Rafa
3
Obwohl die Option technisch über runCommand vor 2.6 verfügbar ist, kann nicht garantiert werden, dass sie korrekte Ergebnisse liefert, und sie sollte nicht empfohlen werden. Sie sollten dies wirklich nur in 2.5.3 oder neuer verwenden (und erwarten, dass vor der Version 2.6 noch einige Fehler lauern).
Stennie
20

Das Aggregations-Framework

Das Aggregationsframework besteht aus einer Reihe von Analysetools MongoDB, mit denen wir verschiedene Arten von Berichten oder Analysen für Dokumente in einer oder mehreren Sammlungen ausführen können. Basierend auf der Idee einer Pipeline. Wir nehmen Eingaben aus einer MongoDBSammlung und leiten die Dokumente aus dieser Sammlung durch eine oder mehrere Stufen, von denen jede eine andere Operation an ihren Eingaben ausführt. Jede Stufe nimmt als Eingabe unabhängig von der Stufe, bevor sie als Ausgabe erzeugt wurde. Und die Ein- und Ausgänge für alle Stufen sind ein Strom von Dokumenten. Jede Stufe hat einen bestimmten Job, den sie erledigt. Es erwartet eine bestimmte Form von Dokumenten und erzeugt eine bestimmte Ausgabe, die selbst ein Strom von Dokumenten ist. Am Ende der Pipeline erhalten wir Zugriff auf die Ausgabe.

Aggregationsrahmenphase

Eine einzelne Stufe ist eine Datenverarbeitungseinheit. Jede Stufe nimmt einzeln einen Dokumentenstrom als Eingabe, verarbeitet jedes Dokument einzeln und erzeugt den Ausgangsstrom von Dokumenten. Wieder eins nach dem anderen. Jede Stufe enthält eine Reihe von Reglern oder Tunables, die wir steuern können, um die Stufe so zu parametrisieren, dass sie jede Aufgabe ausführt, an der wir interessiert sind. Eine Stufe führt also eine allgemeine Aufgabe aus - eine allgemeine Aufgabe - und parametrisiert die Stufe für den bestimmten Satz von Dokumenten, mit denen wir arbeiten. Und genau das möchten wir in dieser Phase mit diesen Dokumenten tun. Diese einstellbaren Elemente haben normalerweise die Form von Operatoren, die wir bereitstellen können, um Felder zu ändern, arithmetische Operationen auszuführen, Dokumente neu zu formen oder eine Art Akkumulationsaufgabe sowie eine Vielzahl anderer Dinge auszuführen. Oft ist es so, dass wir '

Dieselbe Stufe mehrmals innerhalb einer einzelnen Pipeline

zB möchten wir möglicherweise einen ersten Filter durchführen, damit wir nicht die gesamte Sammlung in unsere Pipeline übergeben müssen. Später, nach einer zusätzlichen Verarbeitung, möchten Sie jedoch erneut nach einem anderen Kriteriensatz filtern. Zusammenfassend lässt sich sagen, dass die Pipeline mit einer MongoDBSammlung arbeitet. Sie bestehen aus Stufen, von denen jede eine andere Datenverarbeitungsaufgabe für ihre Eingabe ausführt und Dokumente als Ausgabe erzeugt, die an die nächste Stufe übergeben werden. Und schließlich wird am Ende der Pipeline eine Ausgabe erstellt, mit der wir dann etwas in unserer Anwendung tun können. In vielen Fällen ist es erforderlich, denselben Stufentyp mehrmals in eine einzelne Pipeline aufzunehmen.

Zameer
quelle
Danke, es war hilfreich, um ein besseres Verständnis zu bekommen.
Arun Pratap Singh