MongoDB как проверить наличие

Я хотел бы знать, как я могу проверить существование объекта с помощью mongoDB и С#.

Я нашел способ сделать это, но мне пришлось использовать Linq благодаря методу Any(), но я хотел бы знать, возможно ли это сделать без Linq?

database.GetCollection<ApplicationViewModel>("Applications").Find(Query.EQ("Name", applicationName)).Any()

Спасибо, ребята!

Ответ 1

Используйте $count, чтобы избежать проблем с памятью, не загружая документы из базы данных в память:

int count = items.FindAs<LedgerDocument>(Query.EQ("name", appName)).Count();

if(count > 0)
{
   //then doc exists
}

Оператор $exists в mongodb может использоваться для идентификации того, что какое-либо поле существует в документе, но вы не можете передать ему запрос

database.GetCollection<ApplicationViewModel>("Applications")
                  .Find(Query.Exists("Name", true));

Ответ 2

Простейшим вариантом типа /refactor -safe является использование LINQ * с AsQueryable:

var collection = database.GetCollection<ApplicationViewModel>("Applications");
var exists = collection.AsQueryable().Any(avm => avm.Name == applicationName);

Это создаст команду count и проверит ее выше нуля.

В некоторых случаях (когда производительность является проблемой) вместо подсчета всех соответствующих документов вы можете просто сказать MongoDB, чтобы получить первое и проверить, есть ли он:

var collection = database.GetCollection<ApplicationViewModel>("Applications");
var exists = collection.AsQueryable().FirstOrDefault(avm => avm.Name == applicationName) != null;

Как указал Роберт Стам, в этом случае не имеют значения MongoCollection.Exists и Query.Exists.


* В версии 1.4 (2012-03-27) драйвер поддерживает запросы LINQ (переведенные в запросы mongo, поэтому проблем с памятью нет).

Ответ 3

Способ проверить наличие в версии 2.x драйвера:

bool exists = collection.Find(_ => _.Name == applicationName).Any();

Или асинхронно:

bool exists = await collection.Find(_ => _.Name == applicationName).AnyAsync();;

Ответ 4

MongoCollection.Exists проверяет, существует ли сама коллекция, а не существует ли какой-либо конкретный документ.

Query.Exists(версия построителя запросов $существует) используется для запроса, содержит ли документ конкретное поле (по имени).

Нет "официального" способа запроса, существует или нет документ, соответствующий запросу, но предложение Эндрю Орсича использовать счет, вероятно, является лучшим способом. Они только прокомментируют, что добавлю, что если вы собираетесь обрабатывать соответствующий документ в любом случае, тогда вы также можете пойти и запросить их, используя некоторые варианты поиска.

Ответ 5

Я предлагаю методы, описанные в официальном учебнике

http://www.mongodb.org/display/DOCS/CSharp+Driver+Tutorial#CSharpDriverTutorial-FindandFindAsmethods

Вы можете найти и затем подсчитать, чтобы получить существование.

EDIT: Для исправления проблемы с памятью, похоже, что существует "существует" метод Exists в объекте MongoCollection;)

Ответ 6

Из этой статьи мы читаем:

Однако использовать find() + limit() значительно быстрее, потому что findOne() всегда будет читать + возвращать документ, если он существует. find() просто возвращает курсор (или нет) и считывает данные, только если вы перебираете курсор.

Это означает, что используя что-то вроде:

database.GetCollection<ApplicationViewModel>("Applications").Find(Query.EQ("Name", applicationName)).Limit(1)

вероятно будет самым быстрым.

Ответ 7

Используйте метод CountDocument:

long count = await items.CountDocumentsAsync(yourFilter, null, cancellationToken);

if(count > 0)
{
    //document exists
}