I MongoDB er $sort
aggregeringspipelinestadiet sorterer alle inputdokumenter og returnerer dem til pipelinen i sorteret rækkefølge.
Syntaks
Syntaksen ser sådan ud:
{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }
Hvor 1
for stigende, -1
for faldende, eller { $meta:"textScore" }
at sortere efter den beregnede textScore
metadata i faldende rækkefølge.
Eksempel på data
Antag, at vi har en samling kaldet kæledyr
med følgende dokumenter:
{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "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" : "Dog", "weight" : 30 }
Sortér i stigende rækkefølge
For at sortere i stigende rækkefølge bruger vi 1
for sorteringsrækkefølgen.
Nedenfor er et eksempel på en forespørgsel, der bruger $sort
operatør for at sortere denne samling efter vægt
felt i stigende rækkefølge.
db.pets.aggregate([
{ $sort: { weight: 1 } }
])
Resultat:
{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 } { "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 } { "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 } { "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 } { "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 }
Sortér i faldende rækkefølge
For at sortere i faldende rækkefølge bruger vi -1
for sorteringsrækkefølgen.
db.pets.aggregate([
{ $sort: { weight: -1 } }
])
Resultat:
{ "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 } { "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 } { "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 } { "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 } { "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 } { "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
Sortér efter flere felter
For at sortere efter mere end ét felt skal du adskille hvert felt/sorteringsrækkefølge med et komma.
Eksempel
db.pets.aggregate([
{ $sort: { type: 1, weight: -1, _id: 1 } }
])
Resultat:
{ "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 } { "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 } { "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 } { "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 } { "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 } { "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 }
I dette eksempel sorterede vi efter type
felt i stigende rækkefølge først, derefter efter vægt
felt i faldende rækkefølge, derefter efter _id
felt i stigende rækkefølge.
Dette betyder, at hvis der er flere kæledyr af samme type, er disse kæledyr sorteret efter deres vægt
i faldende rækkefølge. Hvis der er flere kæledyr med både samme type og vægt, sorteres disse kæledyr efter _id
felt i stigende rækkefølge. Hvis vi ikke havde inkluderet _id
felt i sorteringsprocessen, så kunne de kæledyr af samme type og vægt dukke op i vilkårlig rækkefølge. Dette er sandt, hver gang vi kører forespørgslen. Uden at have et sorteringsfelt på et unikt felt (såsom _id
). felt), ville det være fuldt ud muligt (endda sandsynligt), at resultaterne ville komme tilbage i en anden rækkefølge, hver gang forespørgslen blev kørt.
Sortering af forskellige typer
Når man sammenligner værdier af forskellige BSON-typer, bruger MongoDB følgende sammenligningsrækkefølge, fra laveste til højeste:
- MinKey (intern type)
- Nul
- Tal (ints, longs, doubler, decimaler)
- Symbol, streng
- Objekt
- Array
- BinData
- ObjectId
- Boolesk
- Dato
- Tidsstempel
- Regulært udtryk
- MaxKey (intern type)
Antag, at vi har en samling kaldet indlæg med følgende dokumenter:
{ "_id" : 1, "title" : "Web", "body" : "Create a website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" } { "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") } { "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast...", "date" : ISODate("2021-01-01T00:00:00Z") }
Bemærk, at den første dato
feltet indeholder en datostreng, hvorimod de to andre dokumenter bruger et Dato-objekt.
Bemærk også, at datostrengen indeholder nøjagtig samme dato som dokument 3, og denne dato er en senere dato end datoen i dokument 2.
Lad os anvende $sort
til datoen
felter i disse dokumenter:
db.posts.aggregate([
{ $sort: { date: 1 } }
]).pretty()
Resultat:
{ "_id" : 1, "title" : "Web", "body" : "Create a website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" } { "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") } { "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast...", "date" : ISODate("2021-01-01T00:00:00Z") }
I dette tilfælde sorterede vi i stigende rækkefølge, hvilket betyder, at tidligere datoer bør komme først. Vores første dokument indeholder dog en datostreng i stedet for et Date-objekt, og det kom derfor først – selvom dets dato er senere end datoen i dokument 2.
Her er den igen, men i faldende rækkefølge:
db.posts.aggregate([
{ $sort: { date: -1 } }
]).pretty()
Resultat:
{ "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast...", "date" : ISODate("2021-01-01T00:00:00Z") } { "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") } { "_id" : 1, "title" : "Web", "body" : "Create a website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" }
Endnu en gang er datobestillingen ude af stand på grund af de forskellige datatyper.
Sortering af tekstresultatmetadata
Du kan bruge { $meta:"textScore" }
argument for at sortere efter faldende relevansscore ved brug af $text
søgninger.
Eksempel
db.posts.aggregate(
[
{ $match: { $text: { $search: "funny" } } },
{ $sort: { score: { $meta: "textScore" }, title: -1 } }
]
).pretty()
Resultat:
{ "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") }
I dette tilfælde matchede kun ét dokument vores forespørgsel.
I dette eksempel sorterede vi efter { $meta:"textScore" }
, derefter efter title
i faldende rækkefølge. Vi brugte score
som et vilkårligt feltnavn, men dette ignoreres af forespørgselssystemet.
Gør $text
søgninger som denne kræver, at vi har oprettet et tekstindeks. Hvis ikke, en IndexNotFound
fejl vil blive returneret.
Sortering af grupperede resultater
Går tilbage til vores kæledyr
samling, kan vi bruge $sort
trin efter en $group
trin for at sortere en gruppe dokumenter efter antallet af værdier i et bestemt felt.
db.pets.aggregate([
{
$match: { weight: { $lt: 30 } }
},
{
$group: { _id: "$type", count: { $sum: 1 } }
},
{
$sort : { count : -1 }
}
])
Resultat:
{ "_id" : "Cat", "count" : 3 } { "_id" : "Dog", "count" : 2 }
Du kan dog være bedre stillet ved at bruge $sortByCount
operatør i sådanne tilfælde.
Flere oplysninger
Se MongoDB-dokumentationen for mere information.