MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB $sort

In MongoDB ist die $sort Aggregation Pipeline Stage sortiert alle Eingabedokumente und gibt sie in sortierter Reihenfolge an die Pipeline zurück.

Syntax

Die Syntax sieht so aus:

{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }

Wobei <sort order> kann 1 sein für aufsteigend -1 für absteigend oder { $meta: "textScore" } um nach dem berechneten textScore zu sortieren Metadaten in absteigender Reihenfolge.

Beispieldaten

Angenommen, wir haben eine Sammlung namens pets mit folgenden Dokumenten:

{ "_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 }

In aufsteigender Reihenfolge sortieren

Um in aufsteigender Reihenfolge zu sortieren, verwenden wir 1 für die Sortierreihenfolge.

Unten sehen Sie ein Beispiel für eine Abfrage, die $sort verwendet -Operator, um diese Sammlung nach dem weight zu sortieren Feld in aufsteigender Reihenfolge.

db.pets.aggregate([
    { $sort: { weight: 1 } } 
])

Ergebnis:

{ "_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 }

In absteigender Reihenfolge sortieren

Um in absteigender Reihenfolge zu sortieren, verwenden wir -1 für die Sortierreihenfolge.

db.pets.aggregate([
    { $sort: { weight: -1 } } 
])

Ergebnis:

{ "_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 }

Nach mehreren Feldern sortieren

Um nach mehr als einem Feld zu sortieren, trennen Sie jede Feld/Sortierreihenfolge-Kombination durch ein Komma.

Beispiel

db.pets.aggregate([
    { $sort: { type: 1, weight: -1, _id: 1 } }
])

Ergebnis:

{ "_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 }

In diesem Beispiel haben wir nach type sortiert zuerst in aufsteigender Reihenfolge, dann nach weight Feld in absteigender Reihenfolge, dann nach _id Feld in aufsteigender Reihenfolge.

Das bedeutet, wenn es mehrere Haustiere des gleichen Typs gibt, werden diese Haustiere nach ihrem weight sortiert in absteigender Reihenfolge. Wenn es mehrere Haustiere mit demselben Typ und Gewicht gibt, werden diese Haustiere nach der _id sortiert Feld in aufsteigender Reihenfolge. Wenn wir die _id nicht eingefügt hätten Feld im Sortierprozess, dann könnten diese Haustiere der gleichen Art und des gleichen Gewichts in beliebiger Reihenfolge erscheinen. Dies gilt jedes Mal, wenn wir die Abfrage ausführen. Ohne ein Sortierfeld für ein eindeutiges Feld (wie die _id Feld), wäre es durchaus möglich (sogar wahrscheinlich), dass die Ergebnisse jedes Mal, wenn die Abfrage ausgeführt wird, in einer anderen Reihenfolge zurückgegeben würden.

Verschiedene Typen sortieren

Beim Vergleichen von Werten verschiedener BSON-Typen verwendet MongoDB die folgende Vergleichsreihenfolge, vom niedrigsten zum höchsten:

  1. MinKey (interner Typ)
  2. Null
  3. Zahlen (ints, longs, doubles, decimals)
  4. Symbol, Zeichenfolge
  5. Objekt
  6. Array
  7. BinData
  8. Objekt-ID
  9. Boolesch
  10. Datum
  11. Zeitstempel
  12. Regulärer Ausdruck
  13. MaxKey (interner Typ)

Angenommen, wir haben eine Sammlung namens Posts mit den folgenden Dokumenten:

{
	"_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")
}

Beachten Sie, dass das erste date Das Feld enthält eine Datumszeichenfolge, während die anderen beiden Dokumente ein Datumsobjekt verwenden.

Beachten Sie auch, dass die Datumszeichenfolge genau das gleiche Datum wie Dokument 3 enthält und dieses Datum ein späteres Datum als das Datum in Dokument 2 ist.

Wenden wir $sort an bis zum date Felder dieser Dokumente:

db.posts.aggregate([
    { $sort: { date: 1 } } 
]).pretty()

Ergebnis:

{
	"_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")
}

In diesem Fall haben wir in aufsteigender Reihenfolge sortiert, was bedeutet, dass frühere Daten zuerst kommen sollten. Unser erstes Dokument enthält jedoch eine Datumszeichenfolge anstelle eines Datumsobjekts, und daher kam es zuerst – obwohl sein Datum später als das Datum in Dokument 2 ist.

Hier noch einmal, aber in absteigender Reihenfolge:

db.posts.aggregate([
    { $sort: { date: -1 } } 
]).pretty()

Ergebnis:

{
	"_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"
}

Wieder einmal ist die Datumsreihenfolge aufgrund der unterschiedlichen Datentypen aus dem Ruder gelaufen.

Text Score Metadata Sort

Sie können den { $meta: "textScore" } verwenden Argument zum Sortieren nach absteigender Relevanzbewertung bei Verwendung von $text Suchen.

Beispiel

db.posts.aggregate(
   [
     { $match: { $text: { $search: "funny" } } },
     { $sort: { score: { $meta: "textScore" }, title: -1 } }
   ]
).pretty()

Ergebnis:

{
	"_id" : 2,
	"title" : "Animals",
	"body" : "Animals are funny things...",
	"date" : ISODate("2020-01-01T00:00:00Z")
}

In diesem Fall stimmte nur ein Dokument mit unserer Anfrage überein.

In diesem Beispiel haben wir nach { $meta: "textScore" } sortiert , dann nach title in absteigender Reihenfolge. Wir haben score verwendet als beliebiger Feldname, der aber vom Abfragesystem ignoriert wird.

$text ausführen Suchen wie diese erfordern, dass wir einen Textindex erstellt haben. Wenn nicht, ein IndexNotFound Fehler wird zurückgegeben.

Gruppierte Ergebnisse sortieren

Zurück zu unseren pets Sammlung können wir den $sort verwenden Stufe nach einer $group Stufe, um eine Gruppe von Dokumenten nach der Anzahl der Werte in einem bestimmten Feld zu sortieren.

db.pets.aggregate([
    {
      $match: { weight: { $lt: 30 } }
    },
    {
      $group: { _id: "$type", count: { $sum: 1 } }
    },
     { 
      $sort : { count : -1 } 
    }
])

Ergebnis:

{ "_id" : "Cat", "count" : 3 }
{ "_id" : "Dog", "count" : 2 }

Es könnte jedoch besser sein, $sortByCount zu verwenden Betreiber in solchen Fällen.

Weitere Informationen

Weitere Informationen finden Sie in der MongoDB-Dokumentation.