Alexey
Alexey

Reputation: 453

Select all _id from mongodb collection with c# driver

I have large document collection in mongodb and want to get only _id list. Mongodb query is db.getCollection('Documents').find({},{_id : 0, _id: 1}). But in C# query

IMongoCollection<T> Collection { get; set; }

...

List<BsonDocument> mongoResult = this.Collection.FindAsync(FilterDefinition<T>.Empty, new FindOptions<T, BsonDocument>() { Projection = "{ _id: 0, _id: 1 }" }).Result.ToList();

throw exeption InvalidOperationException: Duplicate element name '_id'. I want to get only _id list, other fileds not needed. Documents may have different structures and exclude all other fileds manualy difficult.

What C# query corresponds to the specified mongodb query db.getCollection('Documents').find({},{_id : 0, _id: 1}?

UPDATE: Do not offer solutions related query large amounts of data from the server, for example like

this.Collection.Find(d => true).Project(d => d.Id).ToListAsync().Result;

Upvotes: 7

Views: 9797

Answers (2)

SJFJ
SJFJ

Reputation: 667

Since your using C# driver I would recommend to use the AsQueryable and then use linq instead.

In my opinion it is better since you wouldn't need the magic strings and you would benefit from your linq knowledge. Then it would look something like this

database.GetCollection<T>("collectionname").AsQueryable().Select(x => x.Id);

Upvotes: 5

StuartLC
StuartLC

Reputation: 107277

Alexey is correct, solutions such as these

var result = (await this.Collection<Foos>
                       .Find(_ => true)
                       .ToListAsync())
             .Select(foo => foo.Id);

Will pull the entire document collection over the wire, deserialize, and then map the Id out in Linq To Objects, which will be extremely inefficient.

The trick is to use .Project to return just the _id keys, before the query is executed with .ToListAsync().

You can specify the type as a raw BsonDocument if you don't want to use a strongly typed DTO to deserialize into.

var client = new MongoClient(new MongoUrl(connstring));
var database = client.GetDatabase(databaseName);
var collection = database.GetCollection<BsonDocument>(collectionName);
var allIds = (await collection
        .Find(new BsonDocument()) // OR (x => true)
        .Project(new BsonDocument { { "_id", 1 } })
        .ToListAsync())
    .Select(x => x[0].AsString);

Which executes a query similar to:

db.getCollection("SomeCollection").find({},{_id: 1})

Upvotes: 1

Related Questions