Skip to content

Instantly share code, notes, and snippets.

@alain-andre
Last active May 12, 2021 08:22
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save alain-andre/8150256 to your computer and use it in GitHub Desktop.
Save alain-andre/8150256 to your computer and use it in GitHub Desktop.
Les Aggregations sous MongoDB (informations issues de leurs cours)

Aggregation

Pipeline

  • $project - Sélectionnez, remodeler - 1:1
  • $match - Filtrer - n:1
  • $group - Agréger - n:1
  • $sort - Trier - 1:1
  • $skip - Sauter - n:1
  • $limit - Limiter - n:1
  • $unwind - Découper un champ (array) - 1:n

$project

Permet de remodeler une collection.

Si l'on veut remodeler la collection ci-dessous

{
"city" : "ACMAR",
"loc" : [
	-86.51557,
	33.584132
],
"pop" : 6055,
"state" : "AL",
"_id" : "35004"
}

en

{
"city" : "acmar",
"pop" : 6055,
"state" : "AL",
"zip" : "35004"
}

Il nous faut faire l'aggregation suivante

db.zips.aggregate([
  { $project:
    { 
      _id: 0,
      city: {$toLower: "$city" },
      pop: 1,
      state: 1,
      zip: "$_id"
    }
  }
])

$group

Permet de faire un group by SQL et ainsi de retrouver le nombre de X disponibles pour chaque Y.

{ 
  "_id" : ObjectId("50906d7fa3c412bb040eb58a"), "student_id" : 4, 
  "type" : "homework", 
  "score" : 28.656451042441 
}
>>> db.grades.aggregate([
  {$group:
    { 
      _id:"$type", 
      num: {$sum:1}
    }
  }
])
{
  "result" : [
    {
      "_id" : "homework",
      "num" : 200
    },
    {
      "_id" : "quiz",
      "num" : 200
    },
    {
      "_id" : "exam",
      "num" : 200
    }
  ],
  "ok" : 1
}

$match

Recherche dans la collection. Par exemple les villes dont la population est supérieure à 100 000.

>>> db.zips.aggregate([
  { $match:
    { 
      pop: {$gt: 100000}
    }
  }
])
"result" : [
    {
      "city" : "CHICAGO",
      "loc" : [
        -87.7157,
        41.849015
      ],
      "pop" : 112047,
      "state" : "IL",
      "_id" : "60623"
    },

$sort

Permet de liste par ordre croissant(1) ou décroissant(-1).

db.zips.aggregate([
  { $sort:
    { 
      state: 1,
      city: 1
    }
  }
])

$skip, $limit

Ces opérateur de regroupement ne sont pertinents qu'après un $sort, et sont utilisés dans l'ordre donné.

Ceci par exemple ne donnera aucun résultat à cause de l'ordre $limit 5, $skip 10 donné. Si on limite la liste à 5, en sauter 10 ne retourne rien.

>>> db.zips.aggregate([
  {$match:
    {
      state:"NY"
    }
  },
  {$group:
    {
      _id: "$city",
      population: {$sum:"$pop"},
    }
  },
  {$project:
    {
      _id: 0,
      city: "$_id",
      population: 1,
    }
  },
  {$sort:
    {
      population:-1
    }
  },
  {$limit: 5},
  {$skip: 10} 
])

$first, $last

Retourne le premier ou le dernier élément d'une liste pour chaque groupe donné.

Admettant la collection suivante

{ "_id" : 0, "a" : 0, "b" : 0, "c" : 21 }
{ "_id" : 1, "a" : 0, "b" : 0, "c" : 54 }
{ "_id" : 2, "a" : 0, "b" : 1, "c" : 52 }
{ "_id" : 3, "a" : 0, "b" : 1, "c" : 17 }
{ "_id" : 4, "a" : 1, "b" : 0, "c" : 22 }
{ "_id" : 5, "a" : 1, "b" : 0, "c" : 5 }
{ "_id" : 6, "a" : 1, "b" : 1, "c" : 87 }
{ "_id" : 7, "a" : 1, "b" : 1, "c" : 97 }

L'aggregation suivante nous retourne { "_id" : 1, "a" : 0, "b" : 0, "c" : 54 }

db.fun.aggregate([
    {$match:{a:0}},
    {$sort:{c:-1}}, 
    {$group:{_id:"$a", c:{$first:"$c"}}}
])

$unwind

Éclate un array en autant de documents que d'élément.

Admettant la collection suivante, un $unwind sur likes retournerait 6 documents.

{ 
  "_id" : "Barack Obama", 
  "likes" : [ 
    "social justice", 
    "health care", 
    "taxes" 
  ] 
},
{ 
  "_id" : "Mitt Romney", 
  "likes" : [ 
    "a balanced budget", 
    "corporations", 
    "binders full of women" 
  ] 
}

Les expressions

$sum

Additionne une valeur ou calcule la somme d'un champ

{
  "city" : "CLANTON",
  "loc" : [
    -86.642472,
    32.835532
  ],
  "pop" : 13990,
  "state" : "AL",
  "_id" : "35045"
}

>>> db.zips.aggregate([
 {
  $group:{
   _id: "$state",
   population: {$sum: "$pop"}
  }
 }
])

avg

Calcule la moyenne

>>> db.zips.aggregate([
  { $group:
    { 
      _id: "$state", 
      average_pop: {$avg: "$pop"}
    }
  }
])

addToSet

Ajoute au champ s'il n'existe pas déjà (permet d'obtenir une liste pour un group by)

>>>> db.zips.aggregate([
  { $group:
    { 
      _id: "$city", 
      postal_codes: {$addToSet: "$_id"}
    }
  }
])
{
  "_id" : "CENTREVILLE",
  "postal_codes" : [
    "22020",
    "49032",
    "39631",
    "21617",
    "35042"
  ]
}

$push

Identique à $addToSet sauf qu'il ne garantie pas l'unicité

$max, $min

Retourne la plus grande ou la plus petite valeur du group by

>>> db.zips.aggregate([
  { $group:
    { 
      _id: "$state", 
      pop: {$max: "$pop"}
    }
  }
])
{
  "_id" : "WI",
  "pop" : 57187
},
{
  "_id" : "WV",
  "pop" : 70185
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment