В 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 за повече информация.