$densify

Die $densify Phase in einer Aggregationspipeline wird verwendet, um fehlende Datenpunkte innerhalb einer Abfolge von Werten auszufüllen. Sie hilft beim Erstellen eines vollständigeren Datasets, indem fehlende Werte basierend auf einem angegebenen Feld, Bereich und Schritt generiert werden. Dies ist in Szenarien wie zeitreihenbasierte Datenanalyse hilfreich, bei denen Lücken in Datenpunkten ausgefüllt werden müssen, um eine genaue Analyse sicherzustellen.

Syntax

{
  $densify: {
    field: <field>,
    range: {
      step: <number>,
      unit: <string>, // Optional, e.g., "hour", "day", "month", etc.
      bounds: [<lowerBound>, <upperBound>] // Optional
    },
    partitionByFields: [<field1>, <field2>, ...] // Optional
  }
}

Die Parameter

Parameter Description
field Das Feld, auf dem die Verdichteung ausgeführt wird.
range.step Die Schrittgröße zum Generieren fehlender Werte.
range.unit (Optional) Die Einheit der Schrittgröße, z. B. Zeiteinheiten (z. B. "Stunde", "Tag").
range.bounds (Optional) Gibt den Bereich (untere und obere Begrenzungen) für die Verdichteung an.
partitionByFields (Optional) Felder, die zum Gruppieren von Daten zur Verdichteung verwendet werden.

Examples

Betrachten Sie dieses Beispieldokument aus der Stores-Sammlung.

{
    "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4",
    "name": "First Up Consultants | Beverage Shop - Satterfieldmouth",
    "location": {
        "lat": -89.2384,
        "lon": -46.4012
    },
    "staff": {
        "totalStaff": {
            "fullTime": 8,
            "partTime": 20
        }
    },
    "sales": {
        "totalSales": 75670,
        "salesByCategory": [
            {
                "categoryName": "Wine Accessories",
                "totalSales": 34440
            },
            {
                "categoryName": "Bitters",
                "totalSales": 39496
            },
            {
                "categoryName": "Rum",
                "totalSales": 1734
            }
        ]
    },
    "promotionEvents": [
        {
            "eventName": "Unbeatable Bargain Bash",
            "promotionalDates": {
                "startDate": {
                    "Year": 2024,
                    "Month": 6,
                    "Day": 23
                },
                "endDate": {
                    "Year": 2024,
                    "Month": 7,
                    "Day": 2
                }
            },
            "discounts": [
                {
                    "categoryName": "Whiskey",
                    "discountPercentage": 7
                },
                {
                    "categoryName": "Bitters",
                    "discountPercentage": 15
                },
                {
                    "categoryName": "Brandy",
                    "discountPercentage": 8
                },
                {
                    "categoryName": "Sports Drinks",
                    "discountPercentage": 22
                },
                {
                    "categoryName": "Vodka",
                    "discountPercentage": 19
                }
            ]
        },
        {
            "eventName": "Steal of a Deal Days",
            "promotionalDates": {
                "startDate": {
                    "Year": 2024,
                    "Month": 9,
                    "Day": 21
                },
                "endDate": {
                    "Year": 2024,
                    "Month": 9,
                    "Day": 29
                }
            },
            "discounts": [
                {
                    "categoryName": "Organic Wine",
                    "discountPercentage": 19
                },
                {
                    "categoryName": "White Wine",
                    "discountPercentage": 20
                },
                {
                    "categoryName": "Sparkling Wine",
                    "discountPercentage": 19
                },
                {
                    "categoryName": "Whiskey",
                    "discountPercentage": 17
                },
                {
                    "categoryName": "Vodka",
                    "discountPercentage": 23
                }
            ]
        }
    ]
}

Beispiel 1: Densify a time-series dataset

Diese Abfrage füllt fehlende Tage im Datumsfeld aus.

db.aggregate([
    {
      $documents: [
        { date: new ISODate("2024-01-01"), value: 10 },
        { date: new ISODate("2024-01-03"), value: 15 }
      ]
    },
    {
      $densify: {
        field: "date",
        range: {
          step: 1,
          unit: "day",
          bounds: "full"
        }
      }
    }
  ]);

Diese Abfrage gibt die folgenden Ergebnisse zurück:

[
    {
        "date": "ISODate('2024-01-01T00:00:00.000Z')",
        "value": 10
    },
    {
        "date": "ISODate('2024-01-02T00:00:00.000Z')"
    },
    {
        "date": "ISODate('2024-01-03T00:00:00.000Z')",
        "value": 15
    }
]

Beispiel 2: Verweigerung numerischer Daten

Diese Abfrage füllt fehlende numerische Werte im sales.fullSales Feld aus:

db.aggregate([
    {
      $documents: [
        { level: 1, score: 10 },
        { level: 3, score: 30 }
      ]
    },
    {
      $densify: {
        field: "level",
        range: {
          step: 1,
          bounds: [1, 5] 
        }
      }
    }
  ]);

Diese Abfrage gibt die folgenden Ergebnisse zurück:

[
    {
        "level": 1,
        "score": 10
    },
    {
        "level": 2
    },
    {
        "level": 3,
        "score": 30
    },
    {
        "level": 4
    }
]

Einschränkungen

In der folgenden Tabelle sind die wichtigsten Einschränkungen und Verhaltensweisen zusammengefasst, die der $densify Phase in Aggregationspipelinen zugeordnet sind:

Kategorie Bedingung/Verhalten
Feldeinschränkungen - Fehler, wenn ein Dokument einen Datumswert aufweist und unitnicht angegeben ist.
– Fehler, wenn ein Dokument einen numerischen Wert aufweist und unitangegeben wird.
- Feldname beginnt mit $. Wird $project verwendet, um ihn umzubenennen.
partitionByFields - Jedes Feld wird zu einem Wert ohne Zeichenfolge ausgewertet.
- Feldname beginnt mit $.
range.bounds - Untere Grenze definiert den Startwert unabhängig von vorhandenen Dokumenten.
- Die untere Grenze ist inklusive.
- Obere Grenze ist exklusiv.
- $densify Filtert Dokumente nicht außerhalb der Grenzen aus.