W MongoDB cursor.sort()
Metoda określa kolejność, w jakiej zapytanie zwraca pasujące dokumenty.
sort()
Metoda akceptuje dokument, który określa pole do sortowania i porządek sortowania. Porządek sortowania może być następujący:1
rosnąco lub -1
do zjazdu.
Możesz również określić { $meta: "textScore" }
podczas wykonywania $text
wyszukiwania, aby posortować według obliczonego textScore
metadane w porządku malejącym.
Przykładowe dane
Załóżmy, że mamy kolekcję o nazwie pets
z następującymi dokumentami:
{ "_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 }
Sortuj w porządku rosnącym
Aby posortować w porządku rosnącym, używamy 1
dla porządku sortowania.
Poniżej znajduje się przykład zapytania, które używa $sort
operator do sortowania tej kolekcji według weight
pole w kolejności rosnącej.
db.pets.find().sort({ weight: 1 })
Wynik:
{ "_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 }
Sortuj w porządku malejącym
Aby posortować w porządku malejącym, używamy -1
dla porządku sortowania.
db.pets.find().sort({ weight: -1 })
Wynik:
{ "_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 }
Sortuj według wielu pól
Aby posortować według więcej niż jednego pola, oddziel kombinację każdego pola/porządku sortowania przecinkiem.
Przykład
db.pets.find().sort({ type: 1, weight: -1, _id: 1 })
Wynik:
{ "_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 }
W tym przykładzie posortowaliśmy według type
najpierw pole w kolejności rosnącej, a następnie według weight
pole w kolejności malejącej, a następnie według _id
pole w porządku rosnącym.
Oznacza to, że jeśli istnieje wiele zwierząt tego samego typu, są one sortowane według ich weight
w kolejności malejącej. Jeśli istnieje wiele zwierząt o tym samym typie i wadze, te zwierzęta są sortowane według _id
pole w porządku rosnącym. Gdybyśmy nie uwzględnili _id
w procesie sortowania, wtedy te zwierzęta tego samego typu i wagi mogą pojawić się w dowolnej kolejności. Dzieje się tak za każdym razem, gdy uruchamiamy zapytanie. Bez posiadania pola sortowania w unikalnym polu (takim jak _id
pola), byłoby całkiem możliwe (nawet prawdopodobne), że wyniki będą zwracane w innej kolejności przy każdym uruchomieniu zapytania.
Sortowanie różnych typów
Porównując wartości różnych typów BSON, MongoDB stosuje następującą kolejność porównania, od najniższej do najwyższej:
- MinKey (typ wewnętrzny)
- Numer
- Liczby (int, long, double, dziesiętne)
- Symbol, ciąg
- Obiekt
- Tablica
- BinData
- Identyfikator obiektu
- Boole'a
- Data
- sygnatura czasowa
- Wyrażenie regularne
- MaxKey (typ wewnętrzny)
Załóżmy, że mamy kolekcję o nazwie posty z następującymi dokumentami:
{ "_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") }
Zauważ, że pierwsza date
pole zawiera ciąg daty, podczas gdy pozostałe dwa dokumenty używają obiektu Date.
Zauważ również, że ciąg daty zawiera dokładnie taką samą datę jak w dokumencie 3, a data ta jest późniejsza niż data w dokumencie 2.
Posortujmy według date
pola tych dokumentów:
db.posts.find().sort({ date: 1 }).pretty()
Wynik:
{ "_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") }
W tym przypadku posortowaliśmy w porządku rosnącym, co oznacza, że wcześniejsze daty powinny być pierwsze. Jednak nasz pierwszy dokument zawiera ciąg daty zamiast obiektu Date, więc pojawił się jako pierwszy — mimo że jego data jest późniejsza niż data w dokumencie 2.
I znowu, ale w porządku malejącym:
db.posts.find().sort({ date: -1 }).pretty()
Wynik:
{ "_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" }
Po raz kolejny różne typy danych są uporządkowane osobno.
Sortowanie metadanych wyniku tekstowego
Możesz użyć { $meta: "textScore" }
argument do sortowania według malejącego wyniku trafności przy użyciu $text
wyszukiwania.
Przykład
db.posts.find(
{ $text: { $search: "funny" } },
{ score: { $meta: "textScore" }}
).sort({ score: { $meta: "textScore" } }
).pretty()
Wynik:
{ "_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 }
W tym przykładzie posortowaliśmy według { $meta: "textScore" }
.
Od MongoDB 4.4 linia, która idzie { score: { $meta: "textScore" }}
jest opcjonalne. Pominięcie tego spowoduje pominięcie score
pole z wyników. Dlatego możemy wykonać następujące czynności (z MongoDB 4.4):
db.posts.find(
{ $text: { $search: "funny" } }
).sort({ score: { $meta: "textScore" } }
).pretty()
Wynik:
{ "_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" }
Robienie $text
wyszukiwania takie jak to wymagają utworzenia indeksu tekstowego. Jeśli nie, IndexNotFound
zostanie zwrócony błąd.
Więcej informacji
Więcej informacji znajdziesz w dokumentacji MongoDB.