Dans MongoDB, le $sort
l'étape de pipeline d'agrégation trie tous les documents d'entrée et les renvoie au pipeline dans l'ordre trié.
Syntaxe
La syntaxe ressemble à ceci :
{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }
Où <sort order>
peut être 1
pour l'ascendant, -1
pour décroissant, ou { $meta: "textScore" }
pour trier par le textScore
calculé métadonnées par ordre décroissant.
Exemple de données
Supposons que nous ayons une collection appelée pets
avec les documents suivants :
{ "_id" :1, "name" :"Wag", "type" :"Chien", "weight" :20 }{ "_id" :2, "name" :"Bark", "type" :"Chien", "poids" :10 }{ "_id" :3, "nom" :"Miaou", "type" :"Chat", "poids" :7 }{ "_id" :4, "nom" :"Scratch", "type" :"Chat", "weight" :8 }{ "_id" :5, "name" :"Bruce", "type" :"Kangaroo", "weight" :100 }{ " _id" :6, "name" :"Hop", "type" :"Kangaroo", "weight" :130 }{ "_id" :7, "name" :"Punch", "type" :"Kangaroo", "weight" :200 }{ "_id" :8, "name" :"Snap", "type" :"Cat", "weight" :12 }{ "_id" :9, "name" :"Ruff", "type" :"Chien", "poids" :30 }
Trier par ordre croissant
Pour trier par ordre croissant, nous utilisons 1
pour l'ordre de tri.
Ci-dessous un exemple de requête qui utilise le $sort
opérateur pour trier cette collection par le weight
champ par ordre croissant.
db.pets.aggregate([
{ $sort: { weight: 1 } }
])
Résultat :
{ "_id" :3, "name" :"Meow", "type" :"Chat", "weight" :7 }{ "_id" :4, "name" :"Scratch", "type" :"Chat", "poids" :8 }{ "_id" :2, "nom" :"Aboiement", "type" :"Chien", "poids" :10 }{ "_id" :8, "nom" :"Snap", "type" :"Chat", "weight" :12 }{ "_id" :1, "name" :"Wag", "type" :"Chien", "weight" :20 }{ " _id" :9, "name" :"Ruff", "type" :"Chien", "weight" :30 }{ "_id" :5, "name" :"Bruce", "type" :"Kangourou", "weight" :100 }{ "_id" :6, "name" :"Hop", "type" :"Kangaroo", "weight" :130 }{ "_id" :7, "name" :"Punch", "type" :"Kangourou", "poids" :200 }
Trier par ordre décroissant
Pour trier par ordre décroissant, nous utilisons -1
pour l'ordre de tri.
db.pets.aggregate([
{ $sort: { weight: -1 } }
])
Résultat :
{ "_id" :7, "name" :"Punch", "type" :"Kangaroo", "weight" :200 }{ "_id" :6, "name" :"Hop", "type" :"Kangourou", "poids" :130 }{ "_id" :5, "nom" :"Bruce", "type" :"Kangourou", "poids" :100 }{ "_id" :9, "nom" :"Ruff", "type" :"Chien", "weight" :30 }{ "_id" :1, "name" :"Wag", "type" :"Chien", "weight" :20 }{ " _id" :8, "name" :"Snap", "type" :"Chat", "weight" :12 }{ "_id" :2, "name" :"Bark", "type" :"Chien", "weight" :10 }{ "_id" :4, "name" :"Scratch", "type" :"Cat", "weight" :8 }{ "_id" :3, "name" :"Meow", "type" :"Chat", "poids" :7 }
Trier par plusieurs champs
Pour trier sur plusieurs champs, séparez chaque combo champ/ordre de tri par une virgule.
Exemple
db.pets.aggregate([
{ $sort: { type: 1, weight: -1, _id: 1 } }
])
Résultat :
{ "_id" :8, "name" :"Snap", "type" :"Cat", "weight" :12 }{ "_id" :4, "name" :"Scratch", "type" :"Chat", "poids" :8 }{ "_id" :3, "nom" :"Miaou", "type" :"Chat", "poids" :7 }{ "_id" :9, "nom" :"Ruff", "type" :"Chien", "weight" :30 }{ "_id" :1, "name" :"Wag", "type" :"Chien", "weight" :20 }{ " _id" :2, "name" :"Bark", "type" :"Chien", "weight" :10 }{ "_id" :7, "name" :"Punch", "type" :"Kangourou", "weight" :200 }{ "_id" :6, "name" :"Hop", "type" :"Kangaroo", "weight" :130 }{ "_id" :5, "name" :"Bruce", "type" :"Kangourou", "poids" :100 }
Dans cet exemple, nous avons trié par le type
champ dans l'ordre croissant d'abord, puis par le weight
champ par ordre décroissant, puis par le _id
champ par ordre croissant.
Cela signifie que, s'il y a plusieurs animaux du même type, ces animaux sont triés par leur weight
par ordre décroissant. S'il y a plusieurs animaux avec le même type et le même poids, alors ces animaux sont triés par le _id
champ par ordre croissant. Si nous n'avions pas inclus le _id
champ dans le processus de tri, ces animaux du même type et du même poids pourraient apparaître dans n'importe quel ordre. Cela est vrai à chaque fois que nous exécutons la requête. Sans avoir un champ de tri sur un champ unique (comme le _id
champ), il serait tout à fait possible (voire probable) que les résultats reviennent dans un ordre différent à chaque exécution de la requête.
Trier différents types
Lors de la comparaison des valeurs de différents types de BSON, MongoDB utilise l'ordre de comparaison suivant, du plus bas au plus élevé :
- MinKey (type interne)
- Nul
- Nombres (entiers, longs, doubles, décimaux)
- Symbole, Chaîne
- Objet
- Tableau
- BinData
- ObjectId
- Booléen
- Date
- Horodatage
- Expression régulière
- MaxKey (type interne)
Supposons que nous ayons une collection appelée posts avec les documents suivants :
{ "_id" :1, "title" :"Web", "body" :"Créez un site web en trois étapes simples...", "date" :"2021-01-01T00:00:00.000 Z"}{ "_id" :2, "title" :"Animaux", "body" :"Les animaux sont de drôles de choses...", "date" :ISODate("2020-01-01T00:00:00Z") }{ "_id" :3, "title" :"Océans", "body" :"Les océans sont larges et vastes...", "date" :ISODate("2021-01-01T00:00:00Z")}
Notez que la première date
contient une chaîne de date, alors que les deux autres documents utilisent un objet Date.
Notez également que la chaîne de date contient exactement la même date que le document 3 et que cette date est postérieure à la date du document 2.
Appliquons $sort
à la date
champs de ces documents :
db.posts.aggregate([
{ $sort: { date: 1 } }
]).pretty()
Résultat :
{ "_id" :1, "title" :"Web", "body" :"Créez un site web en trois étapes simples...", "date" :"2021-01-01T00:00:00.000 Z"}{ "_id" :2, "title" :"Animaux", "body" :"Les animaux sont de drôles de choses...", "date" :ISODate("2020-01-01T00:00:00Z") }{ "_id" :3, "title" :"Océans", "body" :"Les océans sont larges et vastes...", "date" :ISODate("2021-01-01T00:00:00Z")}
Dans ce cas, nous avons trié par ordre croissant, ce qui signifie que les dates les plus anciennes doivent venir en premier. Cependant, notre premier document contient une chaîne de date au lieu d'un objet Date, et il est donc venu en premier - même si sa date est postérieure à la date du document 2.
La voici à nouveau, mais dans l'ordre décroissant :
db.posts.aggregate([
{ $sort: { date: -1 } }
]).pretty()
Résultat :
{ "_id" :3, "title" :"Océans", "body" :"Les océans sont larges et vastes...", "date" :ISODate("2021-01-01T00:00:00Z" )}{ "_id" :2, "title" :"Animaux", "body" :"Les animaux sont de drôles de choses...", "date" :ISODate("2020-01-01T00:00:00Z")} { "_id" :1, "title" :"Web", "body" :"Créez un site web en trois étapes simples...", "date" :"2021-01-01T00:00:00.000Z"}
Encore une fois, l'ordre des dates est déséquilibré, en raison des différents types de données.
Trier les métadonnées de score de texte
Vous pouvez utiliser le { $meta: "textScore" }
argument pour trier par score de pertinence décroissant lors de l'utilisation de $text
recherches.
Exemple
db.posts.aggregate(
[
{ $match: { $text: { $search: "funny" } } },
{ $sort: { score: { $meta: "textScore" }, title: -1 } }
]
).pretty()
Résultat :
{ "_id" :2, "title" :"Animaux", "body" :"Les animaux sont de drôles de choses...", "date" :ISODate("2020-01-01T00:00:00Z") }Dans ce cas, un seul document correspondait à notre requête.
Dans cet exemple, nous avons trié par
{ $meta: "textScore" }
, puis partitle
par ordre décroissant. Nous avons utiliséscore
comme un nom de champ arbitraire, mais cela est ignoré par le système de requête.Faire
$text
des recherches comme celle-ci nécessitent que nous ayons créé un index de texte. Sinon, unIndexNotFound
l'erreur sera renvoyée.Trier les résultats groupés
Revenons à nos
pets
collection, nous pouvons utiliser le$sort
étape après un$group
étape pour trier un groupe de documents en fonction du nombre de valeurs dans un champ particulier.db.pets.aggregate([ { $match: { weight: { $lt: 30 } } }, { $group: { _id: "$type", count: { $sum: 1 } } }, { $sort : { count : -1 } } ])
Résultat :
{ "_id" :"Chat", "count" :3 }{ "_id" :"Chien", "count" :2 }Cependant, vous feriez peut-être mieux d'utiliser le
$sortByCount
opérateur dans de tels cas.Plus d'informations
Consultez la documentation MongoDB pour plus d'informations.