MongoDB Daten gruppieren

MongoDBBeginner
Jetzt üben

Einführung

In diesem Lab lernen Sie die Grundlagen der Datenaggregation in MongoDB kennen. Sie konzentrieren sich auf die Verwendung der Aggregationspipeline, um Dokumente zu gruppieren, Berechnungen auf gruppierten Daten durchzuführen und die Ergebnisse anschließend zu filtern, zu sortieren und neu zu gestalten. Diese Operationen sind für die Datenanalyse und Berichterstellung in MongoDB unerlässlich. Am Ende dieses Labs werden Sie mit der Verwendung des $group-Operators sowie anderer wichtiger Aggregationsstufen vertraut sein, um aussagekräftige Erkenntnisse aus Ihren Daten zu gewinnen.

Dokumente nach Feld gruppieren

Der erste Schritt bei der Datenaggregation ist oft das Gruppieren von Dokumenten basierend auf einem gemeinsamen Feld. In diesem Schritt verbinden Sie sich mit der MongoDB-Shell, erstellen eine neue Datenbank und Sammlung und verwenden dann den $group-Operator, um Dokumente nach Kategorie zu gruppieren.

Öffnen Sie zunächst die MongoDB-Shell, indem Sie den folgenden Befehl in Ihrem Terminal ausführen:

mongosh

Sobald Sie sich in der Shell befinden, sehen Sie eine test>-Eingabeaufforderung. Wechseln wir zu einer neuen Datenbank namens salesdb und fügen einige Beispieldaten für Produkte ein. MongoDB erstellt die Datenbank und die Sammlung automatisch, wenn Sie zuerst Daten in diese einfügen.

Kopieren Sie die folgenden Befehle und fügen Sie sie in die mongosh-Shell ein:

use salesdb
db.products.insertMany([
  { category: "Electronics", brand: "Apple", price: 1200 },
  { category: "Electronics", brand: "Samsung", price: 800 },
  { category: "Electronics", brand: "Sony", price: 950 },
  { category: "Apparel", brand: "Nike", price: 150 },
  { category: "Apparel", brand: "Adidas", price: 120 },
  { category: "Books", brand: "Penguin", price: 25 },
  { category: "Books", brand: "Penguin", price: 35 }
]);

Nachdem Sie nun Daten haben, können Sie eine Aggregation durchführen. Der folgende Befehl gruppiert die Dokumente nach dem Feld category und berechnet den Gesamtpreis für jede Kategorie mithilfe des $sum-Akkumulators.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  }
]);

Beispielausgabe:

[
  { "_id": "Books", "totalPrice": 60 },
  { "_id": "Apparel", "totalPrice": 270 },
  { "_id": "Electronics", "totalPrice": 2950 }
]

Lassen Sie uns die Aggregationsstufe aufschlüsseln:

  • db.products.aggregate([...]): Dies ist die Methode, die zur Durchführung der Aggregation verwendet wird. Sie nimmt ein Array von Stufen entgegen, die eine Pipeline bilden.
  • $group: Dies ist der Stufenoperator, der Eingabedokumente gruppiert.
  • _id: "$category": Dieser Ausdruck gibt den Schlüssel an, nach dem gruppiert werden soll. Hier gruppieren wir nach dem Wert des Feldes category. Das $-Präfix zeigt einen Feldpfad an.
  • totalPrice: { $sum: "$price" }: Dies ist ein Akkumulator. Er definiert ein neues Feld im Ausgabedokument namens totalPrice. Der $sum-Operator berechnet die Summe des Feldes price für alle Dokumente in der Gruppe.

Verwendung mehrerer Akkumulatoren

Die $group-Stufe kann mehrere Aggregationen gleichzeitig berechnen. Sie können Durchschnittswerte ermitteln, minimale oder maximale Werte finden und Elemente innerhalb jeder Gruppe zählen. Dieser Schritt zeigt, wie mehrere Akkumulatoren in einer einzigen $group-Stufe verwendet werden.

Sie sollten sich immer noch in der mongosh-Shell befinden und die Datenbank salesdb verwenden.

Schreiben wir eine komplexere Aggregation, die den Gesamtpreis, den Durchschnittspreis und die Anzahl der Produkte für jede Kategorie berechnet.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" },
      averagePrice: { $avg: "$price" },
      productCount: { $sum: 1 }
    }
  }
]);

Beispielausgabe:

[
  {
    "_id": "Books",
    "totalPrice": 60,
    "averagePrice": 30,
    "productCount": 2
  },
  {
    "_id": "Apparel",
    "totalPrice": 270,
    "averagePrice": 135,
    "productCount": 2
  },
  {
    "_id": "Electronics",
    "totalPrice": 2950,
    "averagePrice": 983.3333333333334,
    "productCount": 3
  }
]

Hier sind die neuen Akkumulatoren, die wir verwendet haben:

  • averagePrice: { $avg: "$price" }: Der $avg-Operator berechnet den Durchschnitt des Feldes price für alle Dokumente in der Gruppe.
  • productCount: { $sum: 1 }: Dies ist eine gängige Methode, um Dokumente in einer Gruppe zu zählen. Für jedes Dokument wird 1 zur Summe addiert, wodurch die Dokumente effektiv gezählt werden.

Gefilterte Gruppendaten

Nachdem Daten gruppiert wurden, müssen Sie die Gruppen oft basierend auf den berechneten Werten filtern. Sie möchten beispielsweise nur Kategorien sehen, bei denen der Gesamtumsatz einen bestimmten Betrag übersteigt. Die $match-Stufe wird für diesen Zweck verwendet. Sie kann nach einer $group-Stufe platziert werden, um die gruppierten Dokumente zu filtern.

Suchen wir die Kategorien, bei denen der Gesamtpreis der Produkte größer als 500 ist.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  },
  {
    $match: {
      totalPrice: { $gt: 500 }
    }
  }
]);

Beispielausgabe:

[{ "_id": "Electronics", "totalPrice": 2950 }]

In dieser Pipeline:

  1. Die $group-Stufe berechnet zuerst den totalPrice für jede Kategorie.
  2. Die Ausgabedokumente aus der $group-Stufe werden dann an die $match-Stufe übergeben.
  3. Die $match-Stufe filtert diese Dokumente und behält nur diejenigen, bei denen das Feld totalPrice größer als ($gt) 500 ist.

Dies zeigt die Leistungsfähigkeit der Aggregationspipeline, bei der die Ausgabe einer Stufe zur Eingabe für die nächste wird.

Sortieren von Gruppendaten

Sobald Sie Ihre gruppierten und gefilterten Daten haben, ist der letzte Schritt oft das Sortieren. Die $sort-Stufe ermöglicht es Ihnen, die Dokumente basierend auf einem oder mehreren Feldern in aufsteigender oder absteigender Reihenfolge zu ordnen.

Gruppieren wir die Produkte nach Kategorie, berechnen den Gesamtpreis und sortieren dann die Ergebnisse absteigend nach totalPrice (vom höchsten zum niedrigsten).

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  },
  {
    $sort: {
      totalPrice: -1
    }
  }
]);

Beispielausgabe:

[
  { "_id": "Electronics", "totalPrice": 2950 },
  { "_id": "Apparel", "totalPrice": 270 },
  { "_id": "Books", "totalPrice": 60 }
]

Die $sort-Stufe nimmt ein Dokument entgegen, das die zu sortierenden Felder und die Sortierreihenfolge angibt:

  • totalPrice: -1: Dies sortiert die Dokumente nach dem Feld totalPrice. Der Wert -1 gibt eine absteigende Reihenfolge an. Um aufsteigend zu sortieren, würden Sie 1 verwenden.

Sie können auch nach mehreren Feldern sortieren. Zum Beispiel würde $sort: { category: 1, totalPrice: -1 } zuerst alphabetisch nach dem Kategorienamen und dann absteigend nach dem Gesamtpreis für Kategorien mit demselben Namen sortieren.

Ausgabe mit $project neu gestalten

Manchmal entspricht das Ausgabeformat der $group-Stufe nicht genau dem, was Sie benötigen. Beispielsweise wird der Gruppen-Schlüssel standardmäßig _id genannt. Die $project-Stufe ermöglicht es Ihnen, die Ausgabedokumente umzuformen, indem Felder hinzugefügt, entfernt oder umbenannt werden.

Erstellen wir eine Pipeline, die nach Kategorie gruppiert, nach Gesamtpreis sortiert und dann die Ausgabe so umformt, dass der Kategorie ein beschreibenderer Feldname zugewiesen wird.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  },
  {
    $sort: {
      totalPrice: -1
    }
  },
  {
    $project: {
      _id: 0,
      category: "$_id",
      total: "$totalPrice"
    }
  }
]);

Beispielausgabe:

[
  { "category": "Electronics", "total": 2950 },
  { "category": "Apparel", "total": 270 },
  { "category": "Books", "total": 60 }
]

Die $project-Stufe funktioniert wie folgt:

  • _id: 0: Dies schließt das Feld _id von der Ausgabe aus. Standardmäßig ist _id immer enthalten, es sei denn, es wird explizit ausgeschlossen.
  • category: "$_id": Dies erstellt ein neues Feld namens category und weist ihm den Wert aus dem vorhandenen Feld _id zu.
  • total: "$totalPrice": Dies erstellt ein neues Feld namens total und weist ihm den Wert aus dem Feld totalPrice zu.

Die Verwendung von $project ist eine leistungsstarke Methode, um die endgültige Ausgabe Ihrer Aggregationspipeline für Anwendungen oder Berichte zu formatieren.

Zusammenfassung

In diesem Lab haben Sie gelernt, wie Sie die MongoDB Aggregationspipeline verwenden, um Daten zu gruppieren und zu analysieren. Sie haben mit der Gruppierung von Dokumenten mit dem $group-Operator und der Berechnung von Summen begonnen. Anschließend haben Sie dies erweitert, indem Sie mehrere Akkumulatoren wie $avg und $sum: 1 verwendet haben, um komplexere Berechnungen durchzuführen. Sie haben auch gelernt, wie Sie Aggregationsstufen miteinander verketten, indem Sie $match verwenden, um Ihre gruppierten Ergebnisse zu filtern, $sort, um sie zu ordnen, und $project, um die endgültige Ausgabe in ein sauberes, lesbares Format umzuwandeln. Dies sind grundlegende Fähigkeiten für jeden Entwickler oder Datenanalysten, der mit MongoDB arbeitet.