Nick Farsi
Nick Farsi

Reputation: 427

How to FindOneAsync in MongoDbDriver

It turns out it's very hard to find out how! Current SO answers seem outdated.

var filter = Builders<MyObject>.Filter.Eq(r => r.OriginUrl, originUri.OriginalString);
var shortUrl = await _connector.ShortUrlCollection.Find(filter).FirstOrDefaultAsync();

I really would expect to have FindOneAsync method. Does above work? Or does it scan through all entries first to get one on FirstOrDefaultAsync step?

Upvotes: 1

Views: 968

Answers (1)

Markus
Markus

Reputation: 22491

FirstOrDefaultAsync gets the first batch of results and returns the first document. So if you filter condition matches

  • only one document: only one document is loaded and returned.
  • less documents than your batch size n: only matching documents are loaded, but only the first one is returned.
  • more documents than your batch size n: n documents are loaded, but only the first one is returned.

If you encounter serious performance issues, you could adjust the batch size for the query in the FindOptions to limit the size of the first batch. This class also allows for limiting the number of results to one - at least if you use the generic version:

var filter = Builders<MyObject>.Filter
  .Eq(r => r.OriginUrl, originUri.OriginalString);
var options = new FindOptions<MyObject>()
{
  Limit = 1,
  // Limiting the batch size is not necessary, 
  // if you limit the number of total results to 1 
  // (less than default batch size)
  // BatchSize = 1, 
};
var shortUrl = await (await _connector.ShortUrlCollection.FindAsync(filter, options))
  .FirstOrDefaultAsync();

You can check the implementation of FirstOrDefaultAsync in the driver source code over at github.com.

Upvotes: 1

Related Questions