MongoDB

MongoDB ist die führende Open-Source, Document Datenbank die für einfache Entwicklung und Skalierung aber auch für Big Data Szenarien entwickelt wurde.

MongoDB Aggregation Pipeline in 5 Minuten

Marc-David Militz
Experte
Die Aggregation Pipeline wird verwendet um Daten aus Collections zu verarbeiten und zu einem berechneten Ergebnis zu verarbeiten. MongoDB unterstützt auch Map-Reduce, sowie Single Purpose Aggregations (z.B. count). Die präferierte Methode für Aggregationen ist aber Aggregation Pipeline.

  • ein schnelles Beispiel

    • Wir haben eine Collection mit dem Namen "Posts" ...

      {
      "title" : "mein erster post",
      "author" : "Marc",
      "likes" : 5
      },
      {
      "title" : "mein zweiter post",
      "author" : "Marc",
      "likes" : 2
      },
      {
      "title" : "hello world",
      "author" : "David",
      "likes" : 3
      }

      ... und wir möchten die Anzahl der Likes für jeden Autor haben ...

      db.posts.aggregate([
      {$group: {_id: "$author", total_likes: { $sum: "$likes"}}}
      ])

      ... wir bekommen folgendes Ergebnis ...

      {
      "_id" : "David",
      "total_likes" : 3
      },
      {
      "_id" : "Marc",
      "total_likes" : 7
      }


      • Pipeline Stages

        • Die Aggregation läßt die Dokumente durch verschiedene Stages (Stufen) laufen. Jede Stage transformiert das Dokument während es die Pipeline durchläuft. Im ersten Beispiel haben wir lediglich die "$group" Stage verwendet. Sehen wir uns nun ein Beispiel mit mehreren Stages an.

          db.posts.aggregate([
          {$match: { author: "David"}},
          {$group: {_id: "$author", total_likes: { $sum: "$likes"}}}
          ])

          Das Ergebnis hierfür sieht folgendermassen aus

          {
          "_id" : "David",
          "total_likes" : 3
          }

          Beachte: die "aggregate()" Methode bekommt ein Array von Ausdrücken. Jeder dieser Ausdrücke stellt eine "Stage" dar. Die erste Stage benutzt "$match" um die Dokumente nach dem Namen "David" zu filtern. Die zweite Stage nutzt "$group" um das Ergebnis der ersten Stage zu nehmen und dieses zu anhand des Autors zu gruppieren. Der Akkumulator "$sum" wird verwendet um das Ergebnisfeld "total_likes" für das berechnete Ergebnis zu erzeugen. Wichtig ist dabei zu beachten das die Reihenfolge von Bedeutung ist. Jede Stage ist eine In-Memory Verarbeitung der Dokumente und ist „stateless“. Jede Stage referenziert lediglich das Ergebnis, das von der vorhergehenden Stage erzeugt wurde.

          • Pipeline optimieren

            • Grundsätzlich kann man sagen, daß es eine gute Idee ist Filter und Sortierungen so früh wie möglich in die Pipeline zu setzen. Damit wird die Menge der Dokumente reduziert, die insgesamt verarbeitet werden müssen. Die "$match" und "$sort" Operatoren können von Indexen profitieren, wenn sie am Anfang der Pipeline plaziert werden. Die Aggregation Pipeline hat einen eingebauten Query Optimizer. Wenn möglich, wird MongoDB automatisch eine Abfrage refrakturieren um die Performance zu verbessern.

              Beispiel: aus dieser Abfrage ...

              { $sort: { likes : -1 } },
              { $match: { author: 'Marc' } }

              ... wird diese Abfrage ...

              { $match: { author: 'Marc' } },
              { $sort: { likes : -1 } }

              Das macht Sinn, denn "$match" filtert die Collection bevor "$sort" ausgeführt wird. Das erhöht die Performance, da die Sortierung lediglich auf die gefilterten Dokumente angewendet werden muß. Die Optimierungen sind teilweise spezifisch für die verwendete MongoDB Version und werden automatisch angewendet. Mit der "explain" Option kann man sich ansehen ob der Optimizer die Abfrage "unter der Haube" geändert hat.

              BEACHTE: Es gibt "Blocking" und "Non-Blocking" Stages. "$sort" ist eine Blocking-Stage. d.h. die nächste Stage kann erst ausgeführt werden, wenn das Zwischenergebnis gebildet und wurde. "$match" ist eine Non-Blocking-Stage, d.h. die gefilterten Dokumente können bereits in der nächsten Stage weiterverarbeitet werden, bevor alle Dokumente die Stage durchlaufen haben. Bei Aggregationen mit vielen Stufen oder beim Verarbeiten von großen Datenmengen kann es daher Perfomancevorteile bringen, Blocking-Stages möglichst weit an das Ende der Pipeline zu setzen.

              Die weiteren möglichen Stages werden in der offiziellen MongoDB Dokumentation erläutert. Diese werden auch mit jeder Version erweitert.
              https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/

              • Performance und Limitierungen

                • Die Aggregation Pipeline gibt entweder einen Ergebniscursor zurück oder speichert das Ergebnis in einer Collection. Das Endergebnis hat die MongoDB übliche Limitierung von 16 MB pro Dokument. Zusätzlich dazu ist jede Stage auf 100 MB RAM beschränkt. Dies kann mit der "allowDiskUse" Option umgangen werden, andernfalls wirft MongoDB eine Fehlermeldung.

                  • Zusammenfassung

                    • Die Aggregation Pipeline ist die präferierte Methode um Daten in MongoDB zu aggregieren. Mit der eingebauten Optimierung ist es einfach Daten über verschiedene Stages zu verarbeiten und ein Ergebnis mit einer nativen MongoDB Funktionalität zu erhalten.

                      Wer mehr über die Möglichkeiten des Aggregation Frameworks erfahren möchte, dem sei der Qualiero Kurs für Datenbank Entwickler empfohlen
                      https://www.qualiero.com/lerninhalte/classroom-trainings/mongodb-datenbank-entwickler-kurs.html

Neueste Mitgliederaktivitäten

Diesen Community Beitrag weiterempfehlen