sql >> Database >  >> NoSQL >> MongoDB

MongoDB $sorteren

In MongoDB is de $sort aggregatiepijplijnfase sorteert alle invoerdocumenten en stuurt ze terug naar de pijplijn in gesorteerde volgorde.

Syntaxis

De syntaxis gaat als volgt:

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

Waar <sort order> kan 1 zijn voor oplopend, -1 voor aflopend, of { $meta: "textScore" } om te sorteren op de berekende textScore metagegevens in aflopende volgorde.

Voorbeeldgegevens

Stel dat we een verzameling hebben met de naam pets met de volgende documenten:

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

Sorteren in oplopende volgorde

Om in oplopende volgorde te sorteren, gebruiken we 1 voor de sorteervolgorde.

Hieronder ziet u een voorbeeld van een zoekopdracht die gebruikmaakt van de $sort operator om die verzameling te sorteren op weight veld in oplopende volgorde.

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

Resultaat:

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

Sorteren in aflopende volgorde

Om in aflopende volgorde te sorteren, gebruiken we -1 voor de sorteervolgorde.

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

Resultaat:

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

Sorteren op meerdere velden

Om op meer dan één veld te sorteren, scheidt u elke combinatie van velden/sorteervolgorde met een komma.

Voorbeeld

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

Resultaat:

{ "_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 dit voorbeeld hebben we gesorteerd op het type veld eerst in oplopende volgorde, daarna met het weight veld in aflopende volgorde, dan door de _id veld in oplopende volgorde.

Dit betekent dat, als er meerdere huisdieren van hetzelfde type zijn, die huisdieren worden gesorteerd op hun weight in aflopende volgorde. Als er meerdere huisdieren zijn met hetzelfde type en gewicht, dan worden die huisdieren gesorteerd op _id veld in oplopende volgorde. Als we de _id . niet hadden opgenomen veld in het sorteerproces, dan kunnen die huisdieren van hetzelfde type en gewicht in elke volgorde verschijnen. Dit geldt elke keer dat we de query uitvoeren. Zonder een sorteerveld op een uniek veld (zoals de _id veld), is het heel goed mogelijk (zelfs waarschijnlijk) dat de resultaten elke keer dat de query wordt uitgevoerd in een andere volgorde terugkomen.

Verschillende soorten sorteren

Bij het vergelijken van waarden van verschillende BSON-typen gebruikt MongoDB de volgende vergelijkingsvolgorde, van laag naar hoog:

  1. MinKey (intern type)
  2. Null
  3. Getallen (ints, longs, doubles, decimals)
  4. Symbool, tekenreeks
  5. Object
  6. Array
  7. BinData
  8. Object-ID
  9. Booleaans
  10. Datum
  11. Tijdstempel
  12. Regelmatige expressie
  13. MaxKey (intern type)

Stel dat we een verzameling hebben met de naam posts met de volgende documenten:

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

Merk op dat de eerste date veld een datumstring bevat, terwijl de andere twee documenten een Date-object gebruiken.

Merk ook op dat de datumreeks exact dezelfde datum bevat als document 3, en dat deze datum een ​​latere datum is dan de datum in document 2.

Laten we $sort toepassen naar de date velden van die documenten:

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

Resultaat:

{
	"_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 dit geval hebben we in oplopende volgorde gesorteerd, wat betekent dat eerdere datums eerst moeten komen. Ons eerste document bevat echter een datumstring in plaats van een Date-object, en dus kwam het eerst - ook al is de datum later dan de datum in document 2.

Hier is het weer, maar in aflopende volgorde:

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

Resultaat:

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

Nogmaals, de volgorde van de datum is niet in orde vanwege de verschillende gegevenstypen.

Tekst Score Metadata Sorteren

U kunt de { $meta: "textScore" } . gebruiken argument om te sorteren op aflopende relevantiescore bij gebruik van $text zoekopdrachten.

Voorbeeld

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

Resultaat:

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

In dit geval kwam slechts één document overeen met onze zoekopdracht.

In dit voorbeeld hebben we gesorteerd op { $meta: "textScore" } , dan door title in aflopende volgorde. We gebruikten score als een willekeurige veldnaam, maar dit wordt door het zoeksysteem genegeerd.

$text doen zoekopdrachten als deze vereisen dat we een tekstindex hebben gemaakt. Zo niet, een IndexNotFound fout wordt geretourneerd.

Gegroepeerde resultaten sorteren

Terug naar onze pets verzameling, kunnen we de $sort . gebruiken stage na een $group stap om een ​​groep documenten te sorteren op het aantal waarden in een bepaald veld.

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

Resultaat:

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

U kunt echter beter de $sortByCount . gebruiken operator in dergelijke gevallen.

Meer informatie

Zie de MongoDB-documentatie voor meer informatie.


  1. push nieuwe waarde naar mongodb inner array - mongodb/php

  2. 3 manieren om een ​​datum naar een string te converteren in MongoDB

  3. Werken met sleutels in redis

  4. Vragen met Redis?