22

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!

i3arnon
  • 113,022
  • 33
  • 324
  • 344
John
  • 4,351
  • 9
  • 41
  • 57

7 Answers7

21

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));
Andrew Orsich
  • 52,935
  • 16
  • 139
  • 134
  • Hi 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 ? – John Jun 20 '11 at 14:01
  • @JohnSmith: Sorry it was my mistake, see i updated my answer with correct code. – Andrew Orsich Jun 20 '11 at 14:13
  • thanks you so much for you answer, you made my day. Your code works absolutely fine. I give you 1 vote + Accepted answer. – John Jun 20 '11 at 14:24
  • When are the actual data being fetched from database? Is FindAs<> fetching them? – TechCrap Oct 20 '14 at 21:07
  • What if the count returns 100 billion? Does this not need to limit the count to 1? – GaTechThomas Apr 24 '15 at 20:21
  • 2
    In C# Driver, `var count = _collection.Find(filter).Limit(1).CountAsync().Result;` – Harshal Yelpale Nov 21 '19 at 11:12
  • 2
    A 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 Nov 06 '20 at 13:16
  • 1
    Sadly 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. – Holger Schmeken Nov 25 '20 at 13:58
16

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();;
i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • Your examples don't employ `$limit`, unlike so many other examples. Is that deliberate or an oversight? – mkjeldsen Jul 04 '22 at 06:28
10

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).

i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • 1
    Mongo driver doesn't support all the linq queries. "Unsupported filter: All({document}{subscribers}.Where(({document}{userId} != \"1234\"))). – adi ben Feb 12 '18 at 09:35
3

Use CountDocument method:

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

if(count > 0)
{
    //document exists
}
SeyedPooya Soofbaf
  • 2,654
  • 2
  • 29
  • 31
1

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.

Haris Osmanagić
  • 1,249
  • 12
  • 28
1

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.

Robert Stam
  • 12,039
  • 2
  • 39
  • 36
0

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

Mauro
  • 2,032
  • 3
  • 25
  • 47
  • If memory is the issue, I think this answer is not worth, right? – Mauro Jun 20 '11 at 12:45
  • the 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 http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24exists but I don't know if there're something similar in C#... – John Jun 20 '11 at 12:51
  • yeah 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 Jun 20 '11 at 12:53