sql >> Databáze >  >> NoSQL >> MongoDB

MongoDB $sort

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šší:

  1. MinKey (interní typ)
  2. Nulé
  3. Čísla (ints, longs, double, desetinná místa)
  4. Symbol, řetězec
  5. Objekt
  6. Pole
  7. BinData
  8. ObjectId
  9. Boolovská hodnota
  10. Datum
  11. Časové razítko
  12. Regulární výraz
  13. 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.


  1. Jak naplnit dílčí dokument v mongoose po jeho vytvoření?

  2. Hromadné vkládání Redis

  3. dial tcp [::1]:6397:connectex:Nelze navázat spojení, protože cílový počítač jej aktivně odmítl

  4. python flask jak předat dynamický parametr dekorátoru