$densificar

O $densify estágio em um pipeline de agregação é usado para preencher pontos de dados ausentes dentro de uma sequência de valores. Ele ajuda na criação de um conjunto de dados mais completo gerando valores ausentes com base em um campo, intervalo e etapa especificados. Isso é útil em cenários como análise de dados de série temporal, em que as lacunas nos pontos de dados precisam ser preenchidas para garantir uma análise precisa.

Sintaxe

{
  $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 O campo no qual a densificação é executada.
range.step O tamanho da etapa para gerar valores ausentes.
range.unit (Opcional) A unidade do tamanho da etapa, como unidades de tempo (por exemplo, "hora", "dia").
range.bounds (Opcional) Especifica o intervalo (limites inferior e superior) para densificação.
partitionByFields (Opcional) Campos usados para agrupar dados para densificação.

Exemplos

Considere este documento de exemplo da coleção de documentos das lojas.

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

Exemplo 1: Desnsificar um conjunto de dados de série temporal

Essa consulta preenche os dias ausentes no campo de data.

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 retorna os seguintes 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
    }
]

Exemplo 2: Desnsificar dados numéricos

Essa consulta preenche valores numéricos ausentes no 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 retorna os seguintes resultados:

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

Limitações

A tabela a seguir resume as principais restrições e comportamentos associados ao estágio $densify em pipelines de agregação:

Categoria Condição/Comportamento
Restrições de campo - Erros se qualquer documento tiver um valor de data e unitnão for especificado.
- Erros se qualquer documento tiver um valor numérico e unit for especificado.
- O nome do campo começa com $. Use $project para renomeá-lo.
partitionByFields - Qualquer campo é avaliado como um valor que não seja de cadeia de caracteres .
- O nome do campo começa com $.
range.bounds - O limite inferior define o valor inicial, independentemente dos documentos existentes.
- O limite inferior é inclusivo.
- O limite superior é exclusivo.
- $densify não filtra documentos fora dos limites.