MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

MongoDB $ ordina

In MongoDB, il $sort la fase della pipeline di aggregazione ordina tutti i documenti di input e li restituisce alla pipeline in ordine ordinato.

Sintassi

La sintassi è questa:

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

Dove <sort order> può essere 1 per ascendente, -1 per decrescente o { $meta: "textScore" } per ordinare in base al textScore calcolato metadati in ordine decrescente.

Dati di esempio

Supponiamo di avere una collezione chiamata pets con i seguenti documenti:

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

Ordina in ordine crescente

Per ordinare in ordine crescente, utilizziamo 1 per l'ordinamento.

Di seguito è riportato un esempio di una query che utilizza $sort operatore per ordinare la raccolta in base al weight campo in ordine crescente.

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

Risultato:

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

Ordina in ordine decrescente

Per ordinare in ordine decrescente, utilizziamo -1 per l'ordinamento.

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

Risultato:

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

Ordina per più campi

Per ordinare in base a più campi, separa ogni campo/combinazione di ordinamento con una virgola.

Esempio

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

Risultato:

{ "_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 questo esempio, abbiamo ordinato per type campo prima in ordine crescente, poi in base al weight campo in ordine decrescente, quindi dal _id campo in ordine crescente.

Ciò significa che, se sono presenti più animali domestici dello stesso tipo, tali animali domestici vengono ordinati in base al loro weight in ordine decrescente. Se ci sono più animali domestici con lo stesso tipo e peso, questi animali vengono ordinati in base al _id campo in ordine crescente. Se non avessimo incluso il _id campo nel processo di smistamento, gli animali domestici dello stesso tipo e peso potrebbero apparire in qualsiasi ordine. Questo è vero ogni volta che eseguiamo la query. Senza avere un campo di ordinamento su un campo univoco (come il _id campo), sarebbe del tutto possibile (anche probabile) che i risultati tornino in un ordine diverso ogni volta che viene eseguita la query.

Ordinamento di tipi diversi

Quando si confrontano valori di diversi tipi BSON, MongoDB utilizza il seguente ordine di confronto, dal più basso al più alto:

  1. MinKey (tipo interno)
  2. Nulla
  3. Numeri (int, long, double, decimali)
  4. Simbolo, Stringa
  5. Oggetto
  6. Matrice
  7. BinData
  8. ID oggetto
  9. Booleano
  10. Data
  11. Data e ora
  12. Espressione regolare
  13. MaxKey (tipo interno)

Supponiamo di avere una raccolta chiamata post con i seguenti documenti:

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

Nota che la prima date contiene una stringa di data, mentre gli altri due documenti utilizzano un oggetto Date.

Si noti inoltre che la stringa della data contiene esattamente la stessa data del documento 3 e questa data è successiva alla data nel documento 2.

Applichiamo $sort alla date campi di tali documenti:

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

Risultato:

{
	"_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 questo caso abbiamo ordinato in ordine crescente, il che significa che le date precedenti dovrebbero venire prima. Tuttavia, il nostro primo documento contiene una stringa di data anziché un oggetto Date, quindi è arrivato per primo, anche se la sua data è successiva alla data nel documento 2.

Eccolo di nuovo, ma in ordine decrescente:

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

Risultato:

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

Ancora una volta, l'ordinamento della data è fuori luogo, a causa dei diversi tipi di dati.

Ordinamento metadati punteggio testo

Puoi usare il { $meta: "textScore" } argomento da ordinare in base al punteggio di pertinenza decrescente quando si utilizza $text ricerche.

Esempio

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

Risultato:

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

In questo caso, solo un documento ha soddisfatto la nostra richiesta.

In questo esempio, abbiamo ordinato per { $meta: "textScore" } , quindi da title in ordine decrescente. Abbiamo usato score come nome di campo arbitrario, ma viene ignorato dal sistema di query.

Fare $text ricerche come questa richiedono la creazione di un indice di testo. In caso contrario, un IndexNotFound verrà restituito l'errore.

Ordinamento dei risultati raggruppati

Tornando ai nostri pets raccolta, possiamo usare il $sort fase dopo un $group fase per ordinare un gruppo di documenti in base al numero di valori in un campo particolare.

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

Risultato:

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

Tuttavia, potresti fare meglio a usare $sortByCount operatore in questi casi.

Maggiori informazioni

Consulta la documentazione di MongoDB per ulteriori informazioni.