MongoDB how to check for existence
Solution 1
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));
Solution 2
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();;
Solution 3
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).
Solution 4
Use CountDocument
method:
long count = await items.CountDocumentsAsync(yourFilter, null, cancellationToken);
if(count > 0)
{
//document exists
}
Solution 5
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.
John
Updated on July 09, 2022Comments
-
John almost 2 years
I would like to know how can I check the existence of an object with mongoDB and C#.
I've found a way to do it but I had to use Linq thanks to Any() method, but I'd like to know if it's possible to do it without Linq ?
database.GetCollection<ApplicationViewModel>("Applications").Find(Query.EQ("Name", applicationName)).Any()
Thanks guys!
-
Mauro almost 13 yearsIf memory is the issue, I think this answer is not worth, right?
-
John almost 13 yearsthe memory actually isn't really an issue in my case. I'm just curious to know if the C# driver from 10gen offer an "official" way to check for the existence of a document. Because I saw that with mongo syntax, there're the "exist" keyword as you can see here mongodb.org/display/DOCS/… but I don't know if there're something similar in C#...
-
John almost 13 yearsyeah I saw the Exist keyword from MongoCollection, but it doesn't take any parameter, so how can I filter my list of applications by a particular name ?
-
John almost 13 yearsHi Andrew, how do we filter with what you wrote ? I mean, How can I specify that I want to know if any LedgerDocument.Name == SomethingName exists ?
-
Andrew Orsich almost 13 years@JohnSmith: Sorry it was my mistake, see i updated my answer with correct code.
-
John almost 13 yearsthanks you so much for you answer, you made my day. Your code works absolutely fine. I give you 1 vote + Accepted answer.
-
TechCrap over 9 yearsWhen are the actual data being fetched from database? Is FindAs<> fetching them?
-
GaTechThomas about 9 yearsWhat if the count returns 100 billion? Does this not need to limit the count to 1?
-
adi ben about 6 yearsMongo driver doesn't support all the linq queries. "Unsupported filter: All({document}{subscribers}.Where(({document}{userId} != \"1234\"))).
-
Harshal Yelpale over 4 yearsIn C# Driver,
var count = _collection.Find(filter).Limit(1).CountAsync().Result;
-
Holger Schmeken over 3 yearsA count in any form will count ALL matching documents. This is likely a more complex operation than using the ANY operator that will return immediatly if one matching record is found. Therefore ANY (see @i3arnon) is more efficient for checking the existance.
-
Holger Schmeken over 3 yearsSadly my remark was downvoted. Therefore I like to add the following: the Count operation will count all records that match the search term of Find. Internally this will generate more index and data lookups than necessary to check the pure existance of one match. Here the Any operation will inform the database engine that finding just one record is sufficient to satisfy the Find. As a result the IO, cpu and memory footprint is much smaller with Any than with Count.
-
mkjeldsen almost 2 yearsYour examples don't employ
$limit
, unlike so many other examples. Is that deliberate or an oversight?