Получение документов из базы данных

Последнее обновление: 28.10.2022

Для получения документов из базы данных применяются методы Find()/FindAsync(), которые определены в интерфейсе IMongoCollection. В качестве обязательного параметра эти методы принимают объект BsonDocument, который определяет критерии запроса.

Метод Find() возвращает объект IFindFluent. Для получения результата выборки из этого объекта можно использовать методы ToList()/ToListAsync(), который возвращают список извлеченных из коллекции документов. Например, получим все документы из коллекции "users" из базы данных "test":

sing MongoDB.Bson;
using MongoDB.Driver;

MongoClient client = new MongoClient("mongodb://localhost:27017");

// получаем базу данных test
var db = client.GetDatabase("test");
// получаем из бд коллекцию users
var collection = db.GetCollection<BsonDocument>("users");
// получаем список всех данных
List<BsonDocument> users = await collection.Find(new BsonDocument()).ToListAsync();

foreach(var user in users)
{
    Console.WriteLine(user);
}

Поскольку в данном случае получаем все документы, то в метод Find() в качестве критерия выборки передается пустой объект BsonDocument.

Метод FindAsync() предоставляет результат в виде объекта IAsyncCursor, который представляет собой курсор, который осуществляет перебор объектов. Применив к нему методы ToList()/ToListAsync() также можно получить список объектов:

using MongoDB.Bson;
using MongoDB.Driver;

MongoClient client = new MongoClient("mongodb://localhost:27017");

// получаем базу данных test
var db = client.GetDatabase("test");
// получаем из бд коллекцию users
var collection = db.GetCollection<BsonDocument>("users");
// получаем курсор
using var cursor = await collection.FindAsync(new BsonDocument());
// из курсора получаем список данных
List<BsonDocument> users = cursor.ToList();

foreach(var user in users)
{
    Console.WriteLine(user);
}

Стоит учитывать, что после работы с курсором его необходимо закрыть. В случае выше для этого применяется конструкция using.

Стоит отметить, что мы можем сократить определение фильтра - вместо new BsonDocument() писать сокращенную запись в виде строки "{}":

var users = await collection.Find("{}").ToListAsync();

Получение объектов классов

В предыдущих примерах мы по сути получали набор документов типа BsonDocument. Но подобным образом можно получать объекты стандартных классов C#. Например, в колекции "users" хранятся документы со следующей структурой:

{ "_id" : ObjectId("63581e47224917fbf6a66797"), "Name" : "Tom", "Age" : 38 }

Подобным документам будет соответствовать следующий класс Person:

class Person
{
    public ObjectId Id { get; set; }
    public string Name { get; set; } = "";
    public int Age { get; set; }
}

Получим данные в виде списка объекта Person (пример с FindAsync()):

using MongoDB.Bson;
using MongoDB.Driver;

MongoClient client = new MongoClient("mongodb://localhost:27017");

// получаем базу данных test
var db = client.GetDatabase("test");
// получаем из бд коллекцию users
var collection = db.GetCollection("users");
// получаем курсор
using var cursor = await collection.FindAsync(new BsonDocument());
// из курсора получаем список данных
List users = cursor.ToList();

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; }
}

Аналогичный пример с Find():

using MongoDB.Bson;
using MongoDB.Driver;

MongoClient client = new MongoClient("mongodb://localhost:27017");

// получаем базу данных test
var db = client.GetDatabase("test");
// получаем из бд коллекцию users
var collection = db.GetCollection("users");
// получаем список данных
List users = await collection.Find(new BsonDocument()).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; }
}

Таким образом, мы можем использовать коллекцию как набор объектов BsonDocument или Person. Однако все же BsonDocument могут в некоторых ситуациях оказаться более гибкими, чем стандратные Poco-классы C#. Например, работая с BsonDocument, мы можем сохранять значения разных полей, определять новые дополнительные поля. В случае же с классом Person, если при извлекаемый документ имеет поля, для которых нет соответствующих свойств в классе Person, то программа выдаст ошибку о невозможности связать поля документов из бд со свойствами Person. Если нам эти свойства не принципиальны, то к классу можно применить атрибут [BsonIgnoreExtraElements], который поволит игнорировать все ненужные поля документов:

using MongoDB.Bson.Serialization.Attributes;
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("{}").ToListAsync();
foreach (var user in users) Console.WriteLine(user.Name);

[BsonIgnoreExtraElements]
class Person
{
    public string Name { get; set; } = "";
}

Количество документов

Для получения количества документов в выборке применяются методы CountDocuments()/CountDocumentsAsync() объекта IMongoCollection. В качестве параметра они принимают фильтр документов. Например, получим количество всех документов коллекции:

using MongoDB.Bson;
using MongoDB.Driver;

MongoClient client = new MongoClient("mongodb://localhost:27017");

var db = client.GetDatabase("test"); 
var collection = db.GetCollection("users");

long count = await collection.CountDocumentsAsync(new BsonDocument());
Console.WriteLine(count);

В данном случае также можно было бы получить количество документов следующим образом:

long count = await collection.Find(new BsonDocument()).CountDocumentsAsync();

Другой пример. Найдем количество документов, в которых поле "Name" равно "Tom":

long count = await collection.CountDocumentsAsync(new BsonDocument("Name", "Tom"));
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850