34

How would I translate this mongo query to a Query.EQ statement in C#?

db.users.find({name: 'Bob'}, {'_id': 1});

In other words, I don't want everything returned to C# -- Just the one element I need, the _id. As always, the Mongo C# Driver tutorial is not helpful.

Andrew Orsich
  • 52,935
  • 16
  • 139
  • 134
carlbenson
  • 3,177
  • 5
  • 35
  • 54

4 Answers4

40

Update: With new driver version (1.6+) you can avoid fields names hard-coding by using linq instead:

var users = usersCollection.FindAllAs<T>()
                           .SetFields(Fields<T>.Include(e => e.Id, e => e.Name));

You can do it via SetFields method of mongodb cursor:

var users = usersCollection.FindAllAs<T>()
                 .SetFields("_id") // include only _id
                 .ToList();

By default SetFields includes specified fields. If you need exclude certain fields you can use:

var users = usersCollection.FindAllAs<T>()
                 .SetFields(Fields.Exclude("_id")) // exclude _id field
                 .ToList();

Or you can use them together:

var users = usersCollection.FindAllAs<T>()
                 .SetFields(Fields.Exclude("_id")   // exclude _id field
                                  .Include("name")) // include name field
                 .ToList();
user1069816
  • 2,763
  • 2
  • 26
  • 43
Andrew Orsich
  • 52,935
  • 16
  • 139
  • 134
31

Starting from v2.0 of the driver there's a new async-only API. The old API should no longer be used as it's a blocking facade over the new API and is deprecated.

The currently recommended way to include or exclude certain members is to use the Project method on the IFindFluent you get from Find.

You can either pass a lambda expression:

var result = await collection.Find(query).Project(hamster => hamster.Id).ToListAsync();

Or use the projection builder:

var result = await collection.Find(query)
    .Project<Hamster>(Builders<Hamster>.Projection.Include(hamster => hamster.Id))
    .ToListAsync();

var result = await collection.Find(query)
    .Project<Hamster>(Builders<Hamster>.Projection.Exclude(hamster => hamster.FirstName).
        Exclude(hamster => hamster.LastName))
    .ToListAsync();
i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • But the Project method only filters the result int the memory. The whole document is being fetched from the server, This is bad if the document is big. There must be some other API call in the c# driver that makes the query fetch only specific fields. – Yaron Levi Jun 05 '15 at 16:16
  • 6
    @YaronLevi No, `Project` **does not** only filter in memory. **It is** the API that fetches only specific fields. – i3arnon Jun 05 '15 at 17:30
  • Does method this require the class to be registered (i.e. `BsonClassMap.RegisterClassMap...`)? – MoonKnight Jul 01 '15 at 17:58
  • @Killercam you need to be able to serialize the objects you store in MongoDB. Whether you do that with BsonClassMap or with attributes doesn't matter. – i3arnon Jul 01 '15 at 18:09
  • This is really helpful info actually, it's not immediately intuitive from the documentation. – Pogrindis Oct 19 '18 at 14:39
4

Update You could use a projection and FindAsync which returns a cursor and doesn't load all documents at once unlike Find. You can also set a sort order and limit for number of documents returned.

    var findOptions = new FindOptions<BsonDocument>();

    findOptions.Projection = "{'_id': 1}";

    // Other options
    findOptions.Sort = Builders<BsonDocument>.Sort.Ascending("name");           
    findOptions.Limit = int.MaxValue;

    var collection = context.MongoDatabase.GetCollection<BsonDocument>("yourcollection");   

    using (var cursor = collection.FindSync("{name : 'Bob'}", options))
    {
        while (cursor.MoveNext())
        {
            var batch = cursor.Current;
            foreach (BsonDocument document in batch)
            {
                // do stuff...
            }
        }
    }
clD
  • 2,523
  • 2
  • 22
  • 38
0

here's a simple way to retrieve just the id as you need:

using MongoDB.Driver.Linq;
using MongoDB.Entities;
using System.Linq;

namespace StackOverflow
{
    public class User : Entity
    {
        public string Name { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            new DB("test");

            (new User { Name = "Bob" }).Save();

            var id = DB.Collection<User>()
                       .Where(u => u.Name == "Bob")
                       .Select(u => u.ID)
                       .First();            
        }
    }
}

mind you, the above code is using the mongodb wrapper library called MongoDB.Entities

Dĵ ΝιΓΞΗΛψΚ
  • 5,068
  • 3
  • 13
  • 26