V MongoDB, $sort
fáze agregačního kanálu seřadí všechny vstupní dokumenty a vrátí je do kanálu v seřazeném pořadí.
Syntaxe
Syntaxe vypadá takto:
{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }
Kde <řadí řazení> může být
1
pro vzestupné -1
pro sestupné nebo { $meta:"textScore" }
seřadit podle vypočteného textScore
metadata v sestupném pořadí.
Ukázková data
Předpokládejme, že máme sbírku nazvanou pets
s následujícími dokumenty:
{ "_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 }
Řadit vzestupně
K řazení ve vzestupném pořadí používáme 1
pro pořadí řazení.
Níže je uveden příklad dotazu, který používá $sort
operátor k seřazení této kolekce podle váhy
pole ve vzestupném pořadí.
db.pets.aggregate([
{ $sort: { weight: 1 } }
])
Výsledek:
{ "_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 }
Řadit sestupně
Pro řazení v sestupném pořadí používáme -1
pro pořadí řazení.
db.pets.aggregate([
{ $sort: { weight: -1 } }
])
Výsledek:
{ "_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 }
Řadit podle více polí
Chcete-li seřadit podle více než jednoho pole, oddělte každé pole/kombinaci pořadí řazení čárkou.
Příklad
db.pets.aggregate([
{ $sort: { type: 1, weight: -1, _id: 1 } }
])
Výsledek:
{ "_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 }
V tomto příkladu jsme třídili podle type
pole nejprve vzestupně a poté podle váhy
pole v sestupném pořadí a poté pomocí _id
pole ve vzestupném pořadí.
To znamená, že pokud existuje více domácích mazlíčků stejného typu, jsou tato zvířata seřazena podle jejich váhy
v sestupném pořadí. Pokud existuje více domácích mazlíčků se stejným typem a hmotností, jsou tato zvířata seřazena podle _id
pole ve vzestupném pořadí. Pokud bychom nezahrnuli _id
pole v procesu třídění, pak se tato zvířata stejného typu a hmotnosti mohou objevit v libovolném pořadí. To platí pokaždé, když spustíme dotaz. Aniž byste měli třídicí pole na jedinečném poli (jako je _id
pole), bylo by zcela možné (dokonce pravděpodobné), že by se výsledky při každém spuštění dotazu vrátily v jiném pořadí.
Řazení různých typů
Při porovnávání hodnot různých typů BSON používá MongoDB následující pořadí porovnání, od nejnižší po nejvyšší:
- MinKey (interní typ)
- Nulé
- Čísla (ints, longs, double, desetinná místa)
- Symbol, řetězec
- Objekt
- Pole
- BinData
- ObjectId
- Boolovská hodnota
- Datum
- Časové razítko
- Regulární výraz
- MaxKey (interní typ)
Předpokládejme, že máme kolekci nazvanou příspěvky s následujícími dokumenty:
{ "_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") }
Všimněte si, že první datum
pole obsahuje řetězec data, zatímco ostatní dva dokumenty používají objekt Date.
Všimněte si také, že řetězec data obsahuje přesně stejné datum jako dokument 3 a toto datum je pozdější datum než datum v dokumentu 2.
Aplikujme $sort
k datu
pole těchto dokumentů:
db.posts.aggregate([
{ $sort: { date: 1 } }
]).pretty()
Výsledek:
{ "_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") }
V tomto případě jsme seřadili vzestupně, což znamená, že dřívější data by měla být na prvním místě. Náš první dokument však obsahuje místo objektu Date řetězec data, a tak byl na prvním místě – i když jeho datum je pozdější než datum v dokumentu 2.
Tady je to znovu, ale v sestupném pořadí:
db.posts.aggregate([
{ $sort: { date: -1 } }
]).pretty()
Výsledek:
{ "_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" }
Opět platí, že řazení podle data není v pořádku kvůli různým typům dat.
Třídění metadat skóre textu
Můžete použít { $meta:"textScore" }
argument pro řazení podle sestupného skóre relevance při použití $text
vyhledávání.
Příklad
db.posts.aggregate(
[
{ $match: { $text: { $search: "funny" } } },
{ $sort: { score: { $meta: "textScore" }, title: -1 } }
]
).pretty()
Výsledek:
{ "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") }
V tomto případě našemu dotazu odpovídal pouze jeden dokument.
V tomto příkladu jsme seřadili podle { $meta:"textScore" }
a poté pomocí title
v sestupném pořadí. Použili jsme skóre
jako libovolný název pole, ale to je ignorováno systémem dotazů.
Provádím $text
vyhledávání jako toto vyžaduje, abychom vytvořili textový index. Pokud ne, IndexNotFound
bude vrácena chyba.
Řazení seskupených výsledků
Vraťme se k našim domácím mazlíčkům
kolekce, můžeme použít $sort
fázi po $skupině
fázi k seřazení skupiny dokumentů podle počtu hodnot v konkrétním poli.
db.pets.aggregate([
{
$match: { weight: { $lt: 30 } }
},
{
$group: { _id: "$type", count: { $sum: 1 } }
},
{
$sort : { count : -1 }
}
])
Výsledek:
{ "_id" : "Cat", "count" : 3 } { "_id" : "Dog", "count" : 2 }
Možná by pro vás bylo lepší použít $sortByCount
v takových případech.
Další informace
Další informace naleznete v dokumentaci MongoDB.