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.

4 Answers 4

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();
Sign up to request clarification or add additional context in comments.

Comments

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

5 Comments

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.
@YaronLevi No, Project does not only filter in memory. It is the API that fetches only specific fields.
Does method this require the class to be registered (i.e. BsonClassMap.RegisterClassMap<Hamster>...)?
@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.
This is really helpful info actually, it's not immediately intuitive from the documentation.
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...
            }
        }
    }

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.