$densify

La $densify fase de una canalización de agregación se usa para rellenar los puntos de datos que faltan dentro de una secuencia de valores. Ayuda a crear un conjunto de datos más completo mediante la generación de valores que faltan en función de un campo, un intervalo y un paso especificados. Esto resulta útil en escenarios como el análisis de datos de serie temporal, donde es necesario rellenar huecos en los puntos de datos para garantizar un análisis preciso.

Syntax

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

Parámetros

Parámetro Description
field Campo en el que se realiza la densificación.
range.step Tamaño del paso para generar valores que faltan.
range.unit (Opcional) Unidad del tamaño del paso, como unidades de tiempo (por ejemplo, "hora", "día").
range.bounds (Opcional) Especifica el intervalo (límites inferiores y superiores) para la densificación.
partitionByFields (Opcional) Campos usados para agrupar datos para la densificación.

Examples

Considere este documento de ejemplo de la colección de tiendas.

{
    "_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
                }
            ]
        }
    ]
}

Ejemplo 1: Densify un conjunto de datos de serie temporal

Esta consulta rellena los días que faltan en el campo de fecha.

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"
        }
      }
    }
  ]);

Esta consulta devuelve los siguientes resultados:

[
    {
        "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
    }
]

Ejemplo 2: Densify datos numéricos

Esta consulta rellena los valores numéricos que faltan en el sales.fullSales campo:

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

Esta consulta devuelve los siguientes resultados:

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

Limitaciones

En la tabla siguiente se resumen las restricciones y comportamientos clave asociados a la fase de $densify en las canalizaciones de agregación:

Categoría Condición o comportamiento
Restricciones de campo - Errores si algún documento tiene un valor de fecha y unitno se especifica.
- Errores si algún documento tiene un valor numérico y unit se especifica.
- El nombre del campo comienza por $. Use $project para cambiarle el nombre.
partitionByFields : cualquier campo se evalúa como un valor que no es de cadena .
- El nombre del campo comienza por $.
range.bounds - El límite inferior define el valor inicial, independientemente de los documentos existentes.
- El límite inferior es inclusivo.
- El límite superior es exclusivo.
- $densify no filtra los documentos fuera de los límites.