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

MongoDB $sort

I MongoDB er $sort aggregeringspipelinestadiet sorterer alle inputdokumenter og returnerer dem til pipelinen i sorteret rækkefølge.

Syntaks

Syntaksen ser sådan ud:

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

Hvor kan være 1 for stigende, -1 for faldende, eller { $meta:"textScore" } at sortere efter den beregnede textScore metadata i faldende rækkefølge.

Eksempel på data

Antag, at vi har en samling kaldet kæledyr med følgende dokumenter:

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

Sortér i stigende rækkefølge

For at sortere i stigende rækkefølge bruger vi 1 for sorteringsrækkefølgen.

Nedenfor er et eksempel på en forespørgsel, der bruger $sort operatør for at sortere denne samling efter vægt felt i stigende rækkefølge.

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

Resultat:

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

Sortér i faldende rækkefølge

For at sortere i faldende rækkefølge bruger vi -1 for sorteringsrækkefølgen.

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

Resultat:

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

Sortér efter flere felter

For at sortere efter mere end ét felt skal du adskille hvert felt/sorteringsrækkefølge med et komma.

Eksempel

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

Resultat:

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

I dette eksempel sorterede vi efter type felt i stigende rækkefølge først, derefter efter vægt felt i faldende rækkefølge, derefter efter _id felt i stigende rækkefølge.

Dette betyder, at hvis der er flere kæledyr af samme type, er disse kæledyr sorteret efter deres vægt i faldende rækkefølge. Hvis der er flere kæledyr med både samme type og vægt, sorteres disse kæledyr efter _id felt i stigende rækkefølge. Hvis vi ikke havde inkluderet _id felt i sorteringsprocessen, så kunne de kæledyr af samme type og vægt dukke op i vilkårlig rækkefølge. Dette er sandt, hver gang vi kører forespørgslen. Uden at have et sorteringsfelt på et unikt felt (såsom _id). felt), ville det være fuldt ud muligt (endda sandsynligt), at resultaterne ville komme tilbage i en anden rækkefølge, hver gang forespørgslen blev kørt.

Sortering af forskellige typer

Når man sammenligner værdier af forskellige BSON-typer, bruger MongoDB følgende sammenligningsrækkefølge, fra laveste til højeste:

  1. MinKey (intern type)
  2. Nul
  3. Tal (ints, longs, doubler, decimaler)
  4. Symbol, streng
  5. Objekt
  6. Array
  7. BinData
  8. ObjectId
  9. Boolesk
  10. Dato
  11. Tidsstempel
  12. Regulært udtryk
  13. MaxKey (intern type)

Antag, at vi har en samling kaldet indlæg med følgende dokumenter:

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

Bemærk, at den første dato feltet indeholder en datostreng, hvorimod de to andre dokumenter bruger et Dato-objekt.

Bemærk også, at datostrengen indeholder nøjagtig samme dato som dokument 3, og denne dato er en senere dato end datoen i dokument 2.

Lad os anvende $sort til datoen felter i disse dokumenter:

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

Resultat:

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

I dette tilfælde sorterede vi i stigende rækkefølge, hvilket betyder, at tidligere datoer bør komme først. Vores første dokument indeholder dog en datostreng i stedet for et Date-objekt, og det kom derfor først – selvom dets dato er senere end datoen i dokument 2.

Her er den igen, men i faldende rækkefølge:

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

Resultat:

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

Endnu en gang er datobestillingen ude af stand på grund af de forskellige datatyper.

Sortering af tekstresultatmetadata

Du kan bruge { $meta:"textScore" } argument for at sortere efter faldende relevansscore ved brug af $text søgninger.

Eksempel

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

Resultat:

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

I dette tilfælde matchede kun ét dokument vores forespørgsel.

I dette eksempel sorterede vi efter { $meta:"textScore" } , derefter efter title i faldende rækkefølge. Vi brugte score som et vilkårligt feltnavn, men dette ignoreres af forespørgselssystemet.

Gør $text søgninger som denne kræver, at vi har oprettet et tekstindeks. Hvis ikke, en IndexNotFound fejl vil blive returneret.

Sortering af grupperede resultater

Går tilbage til vores kæledyr samling, kan vi bruge $sort trin efter en $group trin for at sortere en gruppe dokumenter efter antallet af værdier i et bestemt felt.

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

Resultat:

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

Du kan dog være bedre stillet ved at bruge $sortByCount operatør i sådanne tilfælde.

Flere oplysninger

Se MongoDB-dokumentationen for mere information.


  1. Hvordan sikrer man en unik vare i et array baseret på specifikke felter - mongoDB?

  2. Enheder, der skal bruges til maxdistance og MongoDB?

  3. HBase Performance test ved hjælp af YCSB

  4. Abonner på flere kanaler med samme tråd Jedis