Для сортировки документов применяется метод Sort(), который в качестве параметра принимает определение сортировки. В качестве такого определения может выступать документ BsonDocument.
Для работы возьмем коллекцию, которая, допустим, называется "users" и которая хранит следующие данные:
{ "_id" : ObjectId("63596dc76348749cac779373"), "Name" : "Tom", "Age" : 38, "Languages" : ["english", "german", "spanish"] } { "_id" : ObjectId("63596dc76348749cac779374"), "Name" : "Bob", "Age" : 42, "Languages" : ["english"] } { "_id" : ObjectId("63596dc76348749cac779375"), "Name" : "Sam", "Age" : 25, "Languages" : ["english", "spanish"] } { "_id" : ObjectId("63596dc76348749cac779376"), "Name" : "Alice", "Age" : 33 } { "_id" : ObjectId("63596dc76348749cac779377"), "Name" : "Tom", "Age" : 33, "Languages" : ["english"] }
Например, отсортируем все документы по возрастанию по полю Age:
using MongoDB.Bson; using MongoDB.Driver; MongoClient client = new MongoClient("mongodb://localhost:27017"); var db = client.GetDatabase("test"); var collection = db.GetCollection<BsonDocument>("users"); var users = await collection.Find(new BsonDocument { }).Sort(new BsonDocument("Age", 1)).ToListAsync(); foreach (var user in users) Console.WriteLine(user);
Значение 1 в new BsonDocument("Age", 1)
указывает на направление сортировки - по возрастанию. Так, в данном случае мы получим следующий консольный вывод:
{ "_id" : ObjectId("63596dc76348749cac779375"), "Name" : "Sam", "Age" : 25, "Languages" : ["english", "spanish"] } { "_id" : ObjectId("63596dc76348749cac779376"), "Name" : "Alice", "Age" : 33 } { "_id" : ObjectId("63596dc76348749cac779377"), "Name" : "Tom", "Age" : 33, "Languages" : ["english"] } { "_id" : ObjectId("63596dc76348749cac779373"), "Name" : "Tom", "Age" : 38, "Languages" : ["english", "german", "spanish"] } { "_id" : ObjectId("63596dc76348749cac779374"), "Name" : "Bob", "Age" : 42, "Languages" : ["english"] }
Если мы хотим выполнить сортировку по убыванию, то передается значение -1:
var users = await collection.Find(new BsonDocument { }).Sort(new BsonDocument("Age", -1)).ToListAsync();
Также можно использовать сокращенное определение сортировки в виде строки:
var users = await collection.Find("{}").Sort("{Age:1}").ToListAsync();
Дополнительно метод SortBy() сортирует по возрастанию. Он принимает делегат, который через параметр получает тип документа и возвращает поле/свойство документа, по которому идет сортировка. Например, сортировка по полю "Name":
using MongoDB.Bson; using MongoDB.Driver; MongoClient client = new MongoClient("mongodb://localhost:27017"); var db = client.GetDatabase("test"); var collection = db.GetCollection<BsonDocument>("users"); // сортировка по полю Name var users = await collection.Find("{}").SortBy(d => d["Name"]).ToListAsync(); foreach (var user in users) Console.WriteLine(user);
Здесь коллекция типизирована типом BsonDocument, поэтому в делегат в методе SortBy передается объект BsonDocument, у которого обращаемся к полю Name.
Аналогично работает метод SortByDescending(), который сортирует по убыванию:
var users = await collection.Find("{}").SortByDescending(d => d["Name"]).ToListAsync();
Методы SortBy
и SortByDescending
особенно удобны, когда документ представляет объект кастомного типа. Например:
using MongoDB.Bson; using MongoDB.Driver; MongoClient client = new MongoClient("mongodb://localhost:27017"); var db = client.GetDatabase("test"); var collection = db.GetCollection<Person>("users"); var users = await collection.Find("{}") .SortBy(p=>p.Name) // сортировка по возрастанию по Name .ToListAsync(); foreach (var user in users) Console.WriteLine($"{user.Name} - {user.Age}"); class Person { public ObjectId Id { get; set; } public string Name { get; set; } = ""; public int Age { get; set; } public List<string>? Languages { get; set; } }
В данном случае в качестве типа документов выступает класс Person. Консольный вывод:
Alice - 33 Bob - 42 Sam - 25 Tom - 38 Tom - 33
Класс SortDefinitionBuilder позволяет последовательно применить несколько критериев сортировки:
using MongoDB.Bson; using MongoDB.Driver; MongoClient client = new MongoClient("mongodb://localhost:27017"); var db = client.GetDatabase("test"); var collection = db.GetCollection<BsonDocument>("users"); // сначала сортируем по Name во возврастанию, а затем по Age по убыванию var sortDefinition = Builders<BsonDocument>.Sort.Ascending("Name").Descending("Age"); var users = await collection.Find("{}").Sort(sortDefinition).ToListAsync(); foreach (var user in users) Console.WriteLine(user);
В метод Sort()
передается объект SortDefinitionBuilder, который определяется с помощью свойства Builders<BsonDocument>.Sort
.
С помощью метода Ascending
можно указать поле сортировки по возрастанию, а в с помощью метода Descending
- поле для сортировки по убыванию.
То есть в данном случае сначала документы сортируются по полю Name по возрастанию, а затем (если значение поля Name совпадает) - по полю Age по убыванию. И в данном случае мы получим следующий консольный вывод:
{ "_id" : ObjectId("63596dc76348749cac779376"), "Name" : "Alice", "Age" : 33 } { "_id" : ObjectId("63596dc76348749cac779374"), "Name" : "Bob", "Age" : 42, "Languages" : ["english"] } { "_id" : ObjectId("63596dc76348749cac779375"), "Name" : "Sam", "Age" : 25, "Languages" : ["english", "spanish"] } { "_id" : ObjectId("63596dc76348749cac779373"), "Name" : "Tom", "Age" : 38, "Languages" : ["english", "german", "spanish"] } { "_id" : ObjectId("63596dc76348749cac779377"), "Name" : "Tom", "Age" : 33, "Languages" : ["english"] }
Также мы можем воспользоваться перегруженными версиями и задать критерии фильтрации через лямбда-выражения:
using MongoDB.Bson; using MongoDB.Driver; MongoClient client = new MongoClient("mongodb://localhost:27017"); var db = client.GetDatabase("test"); var collection = db.GetCollection<Person>("users"); // сначала сортируем по Name во возврастанию, а затем по Age по убыванию var sortDefinition = Builders<Person>.Sort.Ascending(p=>p.Name).Descending(p=>p.Age); var users = await collection.Find("{}").Sort(sortDefinition).ToListAsync(); foreach (var user in users) Console.WriteLine($"{user.Name} - {user.Age}"); class Person { public ObjectId Id { get; set; } public string Name { get; set; } = ""; public int Age { get; set; } public List<string>? Languages { get; set; } }
Стоит отметить, что всю эту байду мы можем сократить следующим образом:
var users = await collection.Find("{}").Sort("{Name:1, Age:-1}").ToListAsync();