MongoDB how to check for existence

半城伤御伤魂 提交于 2019-11-30 11:23:54

Use $count operator to avoid memory issues, it not loading documents from database into memory:

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

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

Operator $exists in mongodb can be used to identfy that some field exists in a document, but you can't pass query to it:

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

The simplest, type/refactor-safe option is to use LINQ* with AsQueryable:

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

This will create a count command and verify it's higher than zero.

In certain cases (where performance is an issue) instead of counting all the matching documents you can simply tell MongoDB to get the first and check whether there is one:

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

As Robert Stam pointed, both MongoCollection.Exists and Query.Exists are irrelevant in this case.


*As of version 1.4 (2012-03-27) the driver supports LINQ queries (translated to mongo queries, so there are no memory concerns).

The way to check for existence in the 2.x version of the driver is:

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

Or asynchronously:

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

MongoCollection.Exists checks whether the collection itself exists, not whether a particular document exists.

Query.Exists (the Query builder version of $exists) is used to query whether a document contains a particular field (by name).

There is no "official" way to query whether a document that matches a query exists or not, but the suggestion by Andrew Orsich to use count is probably the best way. They only comment I would add is that if you are going to process the matching document(s) anyway, then you might as well go ahead and query for them using some variation of Find.

I'll suggest the methods depicted in official tutorial

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

You can find and then count to get existence.

EDIT: For fixing memory issue, it seems it "exists" the Exists method in MongoCollection object ;)

From this article we read:

However, it is significantly faster to use find() + limit() because findOne() will always read + return the document if it exists. find() just returns a cursor (or not) and only reads the data if you iterate through the cursor.

That means that using something like:

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

will probably be fastest.

Use CountDocument method:

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

if(count > 0)
{
    //document exists
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!