hholtij
hholtij

Reputation: 2936

Find max in a MongoDB collection using .Net Driver 2

With the 1.10 version of the .NET driver I could do something like this to get the max timestamp in the oplog collection:

this.oplogCollection.AsQueryable<OplogEntry>().Max(o => o.ts);

How can I do that with the new driver 2.0? The documentation is basically non-existent or not helpful, so I am hoping some insiders can shed some light here.

Upvotes: 9

Views: 11894

Answers (4)

CodeFuller
CodeFuller

Reputation: 31282

Since MongoDB.Driver 2.0 the best approach is to use FindOptions instance with specified Limit and Sort fields:

var options = new FindOptions<OplogEntry, OplogEntry>
{
    Limit = 1,
    Sort = Builders<OplogEntry>.Sort.Descending(o => o.ts)
};

var max = (await oplogCollection.FindAsync(FilterDefinition<OplogEntry>.Empty, options)).FirstOrDefault();

Sort and Limit params are processed on server side. Therefore such operation is very efficient with only one result item passed to the client.

Upvotes: 3

hholtij
hholtij

Reputation: 2936

Here's the quickest way to access the last entry in the oplog I have found so far:

this.oplogCollection.Find(new BsonDocument()).Sort(new BsonDocument("$natural", -1)).FirstOrDefaultAsync()

It sorts the oplog in reverse natural order and since the natural order in the oplog is by ascending timestamp, grabbing the last element gives me the max.

This method is very fast and from first experiments it does not seem dependent on the oplog size, since no actual sorting takes place.

The other solutions will decrease in performance with the size of the oplog.

Upvotes: 2

D.Rosado
D.Rosado

Reputation: 5773

You can try this:

var result = await collection.Find(x => true).SortByDescending(d => d.ts).Limit(1).FirstOrDefaultAsync();

BTW $max doesn't give you the biggest value as in Linq or SQL, it specifies the upper exclusive bound of a Find. Documentation here

Upvotes: 11

Janic Duplessis
Janic Duplessis

Reputation: 687

EDIT: Not sure if there is a better way, but this works. I haven't found a way to implement the $max operator easily.

var list = await collection.Aggregate().SortByDescending((a) => a["field"]).FirstAsync();

Upvotes: 6

Related Questions