MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

MongoDB $ сортиране

В MongoDB, $sort Етапът на конвейера на агрегиране сортира всички входни документи и ги връща в конвейера в сортиран ред.

Синтаксис

Синтаксисът е така:

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

Където <sort order> може да бъде 1 за възходящо, -1 за низходящо ниво или { $meta: "textScore" } за сортиране по изчисления textScore метаданни в низходящ ред.

Примерни данни

Да предположим, че имаме колекция, наречена pets със следните документи:

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

Сортиране във възходящ ред

За да сортираме във възходящ ред, използваме 1 за реда на сортиране.

По-долу е даден пример за заявка, която използва $sort оператор за сортиране на тази колекция по weight поле във възходящ ред.

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

Резултат:

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

Сортиране в низходящ ред

За да сортираме в низходящ ред, използваме -1 за реда на сортиране.

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

Резултат:

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

Сортиране по множество полета

За да сортирате по повече от едно поле, отделете комбо всяко поле/ред за сортиране със запетая.

Пример

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

Резултат:

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

В този пример ние сортирахме по type първо във възходящ ред, след това по weight поле в низходящ ред, след това по _id поле във възходящ ред.

Това означава, че ако има няколко домашни любимци от един и същи тип, тези домашни любимци се сортират по тяхното weight в низходящ ред. Ако има няколко домашни любимци с един и същи вид и тегло, тогава тези домашни любимци се сортират по _id поле във възходящ ред. Ако не бяхме включили _id поле в процеса на сортиране, тогава тези домашни любимци от същия вид и тегло могат да се появят в произволен ред. Това е вярно всеки път, когато стартираме заявката. Без да има поле за сортиране в уникално поле (като _id поле), би било напълно възможно (дори вероятно) резултатите да се връщат в различен ред при всяко изпълнение на заявката.

Сортиране на различни типове

Когато сравнява стойности на различни типове BSON, MongoDB използва следния ред на сравнение, от най-ниския към най-високия:

  1. MinKey (вътрешен тип)
  2. Null
  3. Числа (цели, дълги, двойни, десетични)
  4. Символ, низ
  5. Обект
  6. Масив
  7. BinData
  8. ObjectId
  9. Булева
  10. Дата
  11. Часово клеймо
  12. Регулярен израз
  13. MaxKey (вътрешен тип)

Да предположим, че имаме колекция, наречена публикации със следните документи:

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

Забележете, че първата date полето съдържа низ от дата, докато другите два документа използват обект Date.

Също така имайте предвид, че низът с дата съдържа точно същата дата като документ 3 и тази дата е по-късна от датата в документ 2.

Нека приложим $sort до date полета на тези документи:

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

Резултат:

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

В този случай сме сортирали във възходящ ред, което означава, че по-ранните дати трябва да са на първо място. Въпреки това, първият ни документ съдържа низ от дата вместо обект Date и така той дойде първи – въпреки че датата му е по-късна от датата в документ 2.

Ето го отново, но в низходящ ред:

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

Резултат:

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

За пореден път подреждането на датите е неправилно, поради различните типове данни.

Сортиране на метаданни за текстова оценка

Можете да използвате { $meta: "textScore" } аргумент за сортиране по низходящ резултат за релевантност, когато използвате $text търсения.

Пример

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

Резултат:

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

В този случай само един документ съответства на нашата заявка.

В този пример ние сортирахме по { $meta: "textScore" } , след това по title в низходящ ред. Използвахме score като произволно име на поле, но това се игнорира от системата за заявки.

Правете $text търсене като това изисква да сме създали текстов индекс. Ако не, IndexNotFound грешка ще бъде върната.

Сортиране на групирани резултати

Връщайки се към нашите pets колекция, можем да използваме $sort етап след $group етап за сортиране на група документи по броя на стойностите в определено поле.

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

Резултат:

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

Въпреки това може да е по-добре да използвате $sortByCount оператор в такива случаи.

Повече информация

Вижте документацията на MongoDB за повече информация.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Неуспешно стартиране на MongoDB - ***прекратяване след грешка на fastert().

  2. Percona Live 2017 - Резюме на Severalnines

  3. elasticsearch v.s. MongoDB за приложение за филтриране

  4. Актуализирайте елемента в масива, ако съществува, иначе вмъкнете нов елемент в този масив в MongoDb

  5. Метеор и DBRefs