Partager via


$unwind (agrégation)

La phase $unwind de l’infrastructure d’agrégation permet de déconstruire un champ de tableau à partir des documents d’entrée afin de générer un document pour chaque élément. Chaque document de sortie est une copie de l’original, mais la valeur du champ de tableau est remplacée par un seul élément. Cela est particulièrement utile pour normaliser les données stockées dans des tableaux et pour effectuer des opérations sur chaque élément d’un tableau séparément.

Syntaxe

{
  $unwind: {
    path: <field path>,
    includeArrayIndex: <string>, // Optional
    preserveNullAndEmptyArrays: <boolean> // Optional
  }
}

Paramètres

Descriptif
path Chemin d’accès d’un champ de tableau. Il s’agit d’un paramètre obligatoire.
includeArrayIndex Optionnel. Nom d’un nouveau champ pour contenir l’index de tableau de l’élément unwound.
preserveNullAndEmptyArrays Optionnel. Si la valeur est true, si le chemin d’accès est null, manquant ou vide, $unwind génère le document sans aucune modification.

Exemple(s)

Exemple 1 : Dérouler les ventes par catégorie

Pour déconstruire le tableau salesByCategory dans le document du magasin :

db.stores.aggregate([
  {
    $unwind: "$store.sales.salesByCategory"
  }
])

Exemple de sortie

[
  {
    "_id": "7954bd5c-9ac2-4c10-bb7a-2b79bd0963c5",
    "store": {
      "name": "Downtown Store",
      "sales": {
        "totalSales": 15000,
        "salesByCategory": {
          "category": "Electronics",
          "totalSales": 5000
        }
      }
    }
  },
  {
    "_id": "7954bd5c-9ac2-4c10-bb7a-2b79bd0963c5",
    "store": {
      "name": "Downtown Store",
      "sales": {
        "totalSales": 15000,
        "salesByCategory": {
          "category": "Clothing",
          "totalSales": 10000
        }
      }
    }
  }
]

Des documents sont générés, chaque document représentant les informations sur les ventes d’une seule catégorie.

Exemple 2 : Dérouler les événements de promotion avec l’index de tableau

Pour déconstruire le tableau promotionEvents et inclure l’index de tableau dans la sortie :

db.stores.aggregate([
  {
    $unwind: {
      path: "$store.promotionEvents",
      includeArrayIndex: "eventIndex"
    }
  }
])

Exemple de sortie

[
  {
    "_id": "7954bd5c-9ac2-4c10-bb7a-2b79bd0963c5",
    "store": {
      "name": "Downtown Store",
      "promotionEvents": {
        "eventName": "Summer Sale",
        "eventDate": ISODate("2024-08-01T00:00:00Z")
      },
      "eventIndex": 0
    }
  },
  {
    "_id": "7954bd5c-9ac2-4c10-bb7a-2b79bd0963c5",
    "store": {
      "name": "Downtown Store",
      "promotionEvents": {
        "eventName": "Black Friday",
        "eventDate": ISODate("2024-11-25T00:00:00Z")
      },
      "eventIndex": 1
    }
  }
]

Des documents sont générés, chaque document représentant un événement de promotion unique, et le champ eventIndex contient l’index d’origine de l’événement dans le tableau.

Exemple 3 : Dérouler les remises dans les événements de promotion

Pour déconstruire le tableau des remises au sein de chaque événement de promotion et conserver les documents sans remise :

db.stores.aggregate([
  {
    $unwind: {
      path: "$store.promotionEvents.discounts",
      preserveNullAndEmptyArrays: true
    }
  }
])

Exemple de sortie

[
  {
    "_id": "7954bd5c-9ac2-4c10-bb7a-2b79bd0963c5",
    "store": {
      "name": "Downtown Store",
      "promotionEvents": {
        "eventName": "Summer Sale",
        "discounts": {
          "discountType": "Percentage",
          "discountAmount": 20
        }
      }
    }
  },
  {
    "_id": "7954bd5c-9ac2-4c10-bb7a-2b79bd0963c5",
    "store": {
      "name": "Downtown Store",
      "promotionEvents": {
        "eventName": "Black Friday"
      }
    }
  }
]

Des documents sont générés, chaque document représentant une remise unique dans un événement de promotion, et les documents sans remises seront conservés.