In MongoDB, de cursor.sort()
methode specificeert de volgorde waarin de zoekopdracht overeenkomende documenten retourneert.
De sort()
methode accepteert een document dat het te sorteren veld en de sorteervolgorde specificeert. De sorteervolgorde kan ofwel 1
. zijn voor oplopend of -1
voor afdalen.
U kunt ook { $meta: "textScore" }
. specificeren bij het doen van $text
zoekopdrachten, om te sorteren op de berekende textScore
metagegevens in aflopende volgorde.
Voorbeeldgegevens
Stel dat we een verzameling hebben met de naam pets
met de volgende documenten:
{ "_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 }
Sorteren in oplopende volgorde
Om in oplopende volgorde te sorteren, gebruiken we 1
voor de sorteervolgorde.
Hieronder ziet u een voorbeeld van een zoekopdracht die gebruikmaakt van de $sort
operator om die verzameling te sorteren op weight
veld in oplopende volgorde.
db.pets.find().sort({ weight: 1 })
Resultaat:
{ "_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 }
Sorteren in aflopende volgorde
Om in aflopende volgorde te sorteren, gebruiken we -1
voor de sorteervolgorde.
db.pets.find().sort({ weight: -1 })
Resultaat:
{ "_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 }
Sorteren op meerdere velden
Om op meer dan één veld te sorteren, scheidt u elke combinatie van velden/sorteervolgorde met een komma.
Voorbeeld
db.pets.find().sort({ type: 1, weight: -1, _id: 1 })
Resultaat:
{ "_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 }
In dit voorbeeld hebben we gesorteerd op het type
veld eerst in oplopende volgorde, daarna met het weight
veld in aflopende volgorde, dan door de _id
veld in oplopende volgorde.
Dit betekent dat, als er meerdere huisdieren van hetzelfde type zijn, die huisdieren worden gesorteerd op hun weight
in aflopende volgorde. Als er meerdere huisdieren zijn met hetzelfde type en gewicht, dan worden die huisdieren gesorteerd op _id
veld in oplopende volgorde. Als we de _id
. niet hadden opgenomen veld in het sorteerproces, dan kunnen die huisdieren van hetzelfde type en gewicht in elke volgorde verschijnen. Dit geldt elke keer dat we de query uitvoeren. Zonder een sorteerveld op een uniek veld (zoals de _id
veld), is het heel goed mogelijk (zelfs waarschijnlijk) dat de resultaten elke keer dat de query wordt uitgevoerd in een andere volgorde terugkomen.
Verschillende soorten sorteren
Bij het vergelijken van waarden van verschillende BSON-typen gebruikt MongoDB de volgende vergelijkingsvolgorde, van laag naar hoog:
- MinKey (intern type)
- Null
- Getallen (ints, longs, doubles, decimals)
- Symbool, tekenreeks
- Object
- Array
- BinData
- Object-ID
- Booleaans
- Datum
- Tijdstempel
- Regelmatige expressie
- MaxKey (intern type)
Stel dat we een verzameling hebben met de naam posts met de volgende documenten:
{ "_id" : 1, "title" : "Web", "body" : "Create a funny 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, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z") }
Merk op dat de eerste date
veld een datumstring bevat, terwijl de andere twee documenten een Date-object gebruiken.
Merk ook op dat de datumreeks exact dezelfde datum bevat als document 3, en dat deze datum een latere datum is dan de datum in document 2.
Laten we sorteren op date
velden van die documenten:
db.posts.find().sort({ date: 1 }).pretty()
Resultaat:
{ "_id" : 1, "title" : "Web", "body" : "Create a funny 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, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z") }
In dit geval hebben we in oplopende volgorde gesorteerd, wat betekent dat eerdere datums eerst moeten komen. Ons eerste document bevat echter een datumstring in plaats van een Date-object, en dus kwam het eerst - ook al is de datum later dan de datum in document 2.
Hier is het weer, maar in aflopende volgorde:
db.posts.find().sort({ date: -1 }).pretty()
Resultaat:
{ "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast, but definitely not funny...", "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 funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" }
Nogmaals, de verschillende datatypes worden afzonderlijk binnen zichzelf geordend.
Tekst Score Metadata Sorteren
U kunt de { $meta: "textScore" }
. gebruiken argument om te sorteren op aflopende relevantiescore bij gebruik van $text
zoekopdrachten.
Voorbeeld
db.posts.find(
{ $text: { $search: "funny" } },
{ score: { $meta: "textScore" }}
).sort({ score: { $meta: "textScore" } }
).pretty()
Resultaat:
{ "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z"), "score" : 0.6666666666666666 } { "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z"), "score" : 0.6 } { "_id" : 1, "title" : "Web", "body" : "Create a funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z", "score" : 0.5833333333333334 }
In dit voorbeeld hebben we gesorteerd op { $meta: "textScore" }
.
Van MongoDB 4.4 de regel die gaat { score: { $meta: "textScore" }}
is optioneel. Als u dit weglaat, wordt de score
weggelaten veld uit de resultaten. Daarom kunnen we het volgende doen (vanaf MongoDB 4.4):
db.posts.find(
{ $text: { $search: "funny" } }
).sort({ score: { $meta: "textScore" } }
).pretty()
Resultaat:
{ "_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, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z") } { "_id" : 1, "title" : "Web", "body" : "Create a funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" }
$text
doen zoekopdrachten als deze vereisen dat we een tekstindex hebben gemaakt. Zo niet, een IndexNotFound
fout wordt geretourneerd.
Meer informatie
Zie de MongoDB-documentatie voor meer informatie.