Aggregationspipeline

Abgeschlossen

In vielen Fällen benötigen Sie Ihre Abfrage, um bestimmte Dokumente zurückzugeben, die programmatisch mit der find-Methode der Auflistung verarbeitet werden sollen. In anderen Fällen möchten Sie möglicherweise nur eine Aggregation wie eine Summe oder einen Mittelwert zurückgeben. Die Azure Cosmos DB for MongoDB nutzt die Aggregationspipelines von MongoDB, mit denen Ihre Abfragen diese Aggregationen auf Serverebene ausführen können. Dadurch können Sie komplexere Abfragen erstellen.

Aggregationspipeline

Aggregationspipelines verwenden, wie der Name schon sagt, mehrstufige Datenverarbeitungspipelines, die Ergebnisse transformieren und aggregieren. Im Folgenden werden einige der häufigsten Schritte zum Definieren der Pipelines beschrieben.

  • $match: Gibt die Abfragebedingungen an. Verwendet das gleiche Abfrageformat wie die find-Auflistungsmethode. Genau wie die find-Methode und bei Platzierung am Anfang einer Pipeline werden in dieser Phase die verfügbaren Indizes verwendet, um die Leistung zu verbessern.
  • $sort: In dieser Phase werden die Ergebnisse nach einem oder mehreren Feldern sortiert. Sofern nicht die Phasen $project, $unwind oder $group vorausgegangen sind, werden in dieser Phase auch verfügbare Indizes verwendet, um die Leistung zu verbessern.
  • $count: Gibt die Anzahl der Dokumente zurück, die aus der vorherigen Phase übergeben wurden.
  • $project: Listet die Felder auf, die im Resultset zurückgegeben und/oder unterdrückt werden sollen.
  • $unwind: Dekonstruiert ein Array oder untergeordnete Eigenschaften. Gehen Sie sorgfältig vor, wenn Sie $unwind für viele Dokumenten verwenden. Führen Sie ggf. vor der Verwendung des $unwind-Operators eine Filterung durch.
  • $group: In dieser Phase werden Dokumente basierend auf dem _id-Ausdruck gruppiert. Dieser Ausdruck kann ein oder mehrere Felder in Ihren Dokumenten, Transformationen aus Ihren Dokumenten oder anderen vorangegangenen Pipelines umfassen. Sehen wir uns die Pipeline $group etwas genauer an.

$group

Während die Pipelines $match und $sort unsere Aggregationen filtern bzw. in eine bestimmte Reihenfolge bringen, definiert $group nicht nur die Gruppierung der Aggregation, sondern auch die Transformation dieser Gruppierung. Die $group-Pipeline verwendet verschiedene Akkumulatoroperatoren wie $sum und $avg, um die Ergebnisse zu transformieren. Im Folgenden werden einige gängige Akkumulatoroperatoren beschreiben, die in dieser Pipeline verwendet werden.

  • $first: Gibt einen Wert aus dem ersten Dokument für jede Gruppe zurück.
  • $last: Gibt einen Wert aus dem letzten Dokument für jede Gruppe zurück.
  • $min: Gibt den niedrigsten Ausdruckswert für jede Gruppe zurück.
  • $max: Gibt den höchsten Ausdruckswert für jede Gruppe zurück.
  • $avg: Gibt einen Mittelwert numerischer Werte zurück.
  • $sum: Gibt eine Summe numerischer Werte zurück.

Verwenden der Aggregationspipeline zum Abfragen der Daten

Im Folgenden erstellen wir einige Abfrageszenarios, um unsere Aggregationspipelines zu definieren.

Angenommen, wir haben eine Auflistung namens salesReceipts mit den drei folgenden Dokumenten.

    {
        "_id": 1
        , "ReceiptNo": 1000
        , "SalesDetail": [ 
            {"ItemName":"Eggs","quantity":5,"priceperunit":3.55},
            {"ItemName":"Milk","quantity":2,"priceperunit":4.25},
            {"ItemName":"Bread","quantity":1,"priceperunit":1.33}
        ]
    }
    {
        "_id": 2
        , "ReceiptNo": 1001
        , "SalesDetail": [ 
            {"ItemName":"Milk","quantity":1,"priceperunit":4.25},
            {"ItemName":"Eggs","quantity":3,"priceperunit":3.55},
            {"ItemName":"Flour","quantity":1,"priceperunit":2.45}
        ]
    }
    {
        "_id": 3
        , "ReceiptNo": 1002
        , "SalesDetail": [ 
            {"ItemName":"Tomatoes","quantity":10,"priceperunit":0.35},
            {"ItemName":"Lettuce","quantity":1,"priceperunit":0.85},
            {"ItemName":"Onions","quantity":4,"priceperunit":0.57}
        ]
    }

Beispiele für Aggregationspipelines unter Verwendung der Mongo-Shell

Zum Ausführen einer Aggregationspipelineabfrage in der Mongo-Shell verwenden wir die Aggregationsfunktion der Auflistung.

Angenommen, wir möchten eine Abfrage erstellen, die die Anzahl der Belege zurückgibt.

Führen Sie in der Mongo-Shell die folgende Abfrage mit der Abfragepipeline aus.

db.salesReceipts.aggregate(
    [
        {
            $count: "number_of_receipts"
        }
    ]
)

Lassen Sie uns dieses Beispiel etwas breiter fassen. Wir zählen alle Kaufbelege mit dem Posten „Milch“.

db.salesReceipts.aggregate(
    [
        {
            $match: {"SalesDetail.ItemName":"Milk"}
        },
        {
            $count: "number_of_receipts"
        }
    ]
)

Anschließend geben wir die Belegnummer und die Gesamtsumme der einzelnen Belege zurück.

db.salesReceipts.aggregate(
    [
        {
            $unwind: "$SalesDetail"
        },
        {
            $group:
            {
                _id: "$ReceiptNo"
                , ReceiptSales: { $sum: { $multiply: ["$SalesDetail.quantity", "$SalesDetail.priceperunit"]}}
            }
        },
        {
            $project: 
            {   
                ReceiptNumber: "$_id"
                , ReceiptSales: {$round: ["$ReceiptSales",2]  }
                , _id:  0 // projecting with value zero will not display the column named _id
            }
        }
    ]
)

Hinweis

Sie können diese db.collection.aggregate-Funktionen auch im Azure-Portal ausführen, indem Sie die Shell verwenden, die auf der Kontoseite der Azure Cosmos DB for MongoDB enthalten ist. Erweitern Sie unter Daten-Explorer Ihre Datenbank, und wählen Sie die Auflistung aus, für die Sie die Funktion ausführen möchten. Im Auflistungsmenü wird die Option Neue Shell angezeigt.

Wie bereits erläutert, verwendet die Azure Cosmos DB for MongoDB MongoDB-Aggregationspipelines, damit komplexe Abfragen ohne Probleme direkt auf dem Server ausgeführt werden können. Dadurch müssen nicht mehr alle Originaldokumente zurück an den Client gesendet werden, um diese Aggregationen programmatisch zu berechnen.