В MongoDB, cursor.sort()
метод определя реда, в който заявката връща съвпадащи документи.
sort()
методът приема документ, който определя полето за сортиране и реда на сортиране. Редът на сортиране може да бъде 1
за възходящо или -1
за спускане.
Можете също да посочите { $meta: "textScore" }
когато правите $text
търси, за да сортира по изчисления textScore
метаданни в низходящ ред.
Примерни данни
Да предположим, че имаме колекция, наречена pets
със следните документи:
{ "_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 }
Сортиране във възходящ ред
За да сортираме във възходящ ред, използваме 1
за реда на сортиране.
По-долу е даден пример за заявка, която използва $sort
оператор за сортиране на тази колекция по weight
поле във възходящ ред.
db.pets.find().sort({ weight: 1 })
Резултат:
{ "_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 }
Сортиране в низходящ ред
За да сортираме в низходящ ред, използваме -1
за реда на сортиране.
db.pets.find().sort({ weight: -1 })
Резултат:
{ "_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 }
Сортиране по множество полета
За да сортирате по повече от едно поле, отделете комбо всяко поле/ред за сортиране със запетая.
Пример
db.pets.find().sort({ type: 1, weight: -1, _id: 1 })
Резултат:
{ "_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 }
В този пример ние сортирахме по type
първо във възходящ ред, след това по weight
поле в низходящ ред, след това по _id
поле във възходящ ред.
Това означава, че ако има няколко домашни любимци от един и същи тип, тези домашни любимци се сортират по тяхното weight
в низходящ ред. Ако има няколко домашни любимци с един и същи вид и тегло, тогава тези домашни любимци се сортират по _id
поле във възходящ ред. Ако не бяхме включили _id
поле в процеса на сортиране, тогава тези домашни любимци от същия вид и тегло могат да се появят в произволен ред. Това е вярно всеки път, когато стартираме заявката. Без да има поле за сортиране в уникално поле (като _id
поле), би било напълно възможно (дори вероятно) резултатите да се връщат в различен ред при всяко изпълнение на заявката.
Сортиране на различни типове
Когато сравнява стойности на различни типове BSON, MongoDB използва следния ред на сравнение, от най-ниския към най-високия:
- MinKey (вътрешен тип)
- Null
- Числа (цели, дълги, двойни, десетични)
- Символ, низ
- Обект
- Масив
- BinData
- ObjectId
- Булева
- Дата
- Часово клеймо
- Регулярен израз
- MaxKey (вътрешен тип)
Да предположим, че имаме колекция, наречена публикации със следните документи:
{ "_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") }
Забележете, че първата date
полето съдържа низ от дата, докато другите два документа използват обект Date.
Също така имайте предвид, че низът с дата съдържа точно същата дата като документ 3 и тази дата е по-късна от датата в документ 2.
Нека сортираме по date
полета на тези документи:
db.posts.find().sort({ date: 1 }).pretty()
Резултат:
{ "_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") }
В този случай сме сортирали във възходящ ред, което означава, че по-ранните дати трябва да са на първо място. Въпреки това, първият ни документ съдържа низ от дата вместо обект Date и така той дойде първи – въпреки че датата му е по-късна от датата в документ 2.
Ето го отново, но в низходящ ред:
db.posts.find().sort({ date: -1 }).pretty()
Резултат:
{ "_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" }
Отново различните типове данни са подредени отделно в себе си.
Сортиране на метаданни за текстова оценка
Можете да използвате { $meta: "textScore" }
аргумент за сортиране по низходящ резултат за релевантност, когато използвате $text
търсения.
Пример
db.posts.find(
{ $text: { $search: "funny" } },
{ score: { $meta: "textScore" }}
).sort({ score: { $meta: "textScore" } }
).pretty()
Резултат:
{ "_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 }
В този пример ние сортирахме по { $meta: "textScore" }
.
От MongoDB 4.4 реда, който върви { score: { $meta: "textScore" }}
е по избор. Пропускането на това ще пропусне score
поле от резултатите. Следователно можем да направим следното (от MongoDB 4.4):
db.posts.find(
{ $text: { $search: "funny" } }
).sort({ score: { $meta: "textScore" } }
).pretty()
Резултат:
{ "_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
търсене като това изисква да сме създали текстов индекс. Ако не, IndexNotFound
грешка ще бъде върната.
Повече информация
Вижте документацията на MongoDB за повече информация.