MongoDB how to check for existence

33,378

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.

Share:
33,378
John
Author by

John

Updated on July 09, 2022

Comments

  • John
    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
    Mauro almost 13 years
    If memory is the issue, I think this answer is not worth, right?
  • John
    John almost 13 years
    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 mongodb.org/display/DOCS/… but I don't know if there're something similar in C#...
  • John
    John almost 13 years
    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
    John almost 13 years
    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 ?
  • Andrew Orsich
    Andrew Orsich almost 13 years
    @JohnSmith: Sorry it was my mistake, see i updated my answer with correct code.
  • John
    John almost 13 years
    thanks you so much for you answer, you made my day. Your code works absolutely fine. I give you 1 vote + Accepted answer.
  • TechCrap
    TechCrap over 9 years
    When are the actual data being fetched from database? Is FindAs<> fetching them?
  • GaTechThomas
    GaTechThomas about 9 years
    What if the count returns 100 billion? Does this not need to limit the count to 1?
  • adi ben
    adi ben about 6 years
    Mongo driver doesn't support all the linq queries. "Unsupported filter: All({document}{subscribers}.Where(({document}{userId} != \"1234\"))).
  • Harshal Yelpale
    Harshal Yelpale over 4 years
    In C# Driver, var count = _collection.Find(filter).Limit(1).CountAsync().Result;
  • Holger Schmeken
    Holger Schmeken over 3 years
    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
    Holger Schmeken over 3 years
    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.
  • mkjeldsen
    mkjeldsen almost 2 years
    Your examples don't employ $limit, unlike so many other examples. Is that deliberate or an oversight?