Search code examples
c#mongodbmongodb-.net-driver

MongoDB - Inserting the result of a query in one round-trip


Consider this hypothetical snippet:

using (mongo.RequestStart(db))
{
    var collection = db.GetCollection<BsonDocument>("test");

    var insertDoc = new BsonDocument { { "currentCount", collection.Count() } };
    WriteConcernResult wcr = collection.Insert(insertDoc);
}

It inserts a new document with "currentCount" set to the value returned by collection.Count().

This implies two round-trips to the server. One to calculate collection.Count() and one to perform the insert. Is there a way to do this in one round-trip?

In other words, can the value assigned to "currentCount" be calculated on the server at the time of the insert?

Thanks!


Solution

  • There is no way to do this currently (Mongo 2.4).

    The upcoming 2.6 version should have batch operations support but I don't know if it will support batching operations of different types and using the results of one operation from another operation.

    What you can do, however, is execute this logic on the server by expressing it in JavaScript and using eval:

    collection.Database.Eval(new BsonJavaScript(@"
      var count = db.test.count();
      db.test.insert({ currentCount: count });
    ");
    

    But this is not recommended, because of several reasons: you lose the write concern, it is very unsafe in terms of security, it requires admin permissions, it holds a global write lock, and it won't work on sharded clusters :)

    I think your best route at the moment would be to do this in two queries. If you're looking for atomic updates or counters (which don't exactly match your example but seem somewhat related), take a look at findAndModify and the $inc operator of update.