Performing Updates With CSMongo

I received some very good questions earlier today about how to perform updates on records in CSMongo. Rather than doing a short answer in a comment I figured a full post about it might be more helpful. While playing with this I made some changes to the code so if you have a previous version then you're going to want to update to the newest version.

CSMongo has a couple ways available to update records right now. One is after you have made a selection from a database and the other is a query sent to the database.

Update After Selection

If you've used LINQ to SQL before then you know that you can load database objects into memory, modify them and then submit the changes and like magic your records are updated... maybe not real magic but I was still impressed the first time I saw it...

CSMongo allows for a similar approach when performing updates on documents loaded from the database. For example, here is how we could load a set of users, modify them and then issue back our changes.

//connect to the database
using (MongoDatabase database = new MongoDatabase(connectionString)) {

    //load a set of records
    MongoCollection collection = database.GetCollection("drivers");

    //select a set of records
    var drivers = collection.Find()
        .Greater("age", 16)
        .Select();

    //make some changes
    drivers.Apply(new {
        canDrive = true
    });

    //submit the changes
    collection.SubmitChanges();

}

This code load in a set of records and saves their reference to the collection (which is also managed by the MongoDatabase class in case you were wondering). This allows you to make changes to your object in multiple places and then call SubmitChanges to apply everything you've done.

When the record is first loaded a hash is created of the object which is used to check for changes which means that if you don't change anything, or if values are set but not actually different then the update request is never sent.

It is also important to realize that MongoCollection.SubmitChanges() only sends updates for the collection that is called on whereas MongoDatabase.SubmitChanges() checks all of the collections that have been loaded and attempts to apply their changes. This is actually one of the advantages to using the MongoDatabase to create instances of your MongoCollection since it can automatically handle checking for changes.

In this last example we don't actually use any of the information in the record which makes loading it into memory first rather pointless which leads us into the next type of update.

Immediate Updates

Sometimes when you want to change records you don't want to have to load them first. Sometimes you simply want to perform and update for a bunch of matching records that meet a certain condition. In that instance you can issue an update immediately from a MongoQuery.

The example we used above is a good example where sending an update would be better than loading the records first. There isn't a lot that changes but what happens in the background is much different.

//connect to the database
using (MongoDatabase database = new MongoDatabase(connectionString)) {

    //issue the query directly from the database level
    database.From("drivers")
        .Greater("age", 16)
        .Set(new {
            canDrive = true
        });

}

You can also perform an update directly from the MongoCollection by using the Find() command, which starts a MongoQuery that can be used for the update.

You may notice that this example doesn't have a call to SubmitChanges() in it -- That's because when I say immediate then by golly, I mean right away! In fact, if I remember correctly ever command on the MongoDatabase level is evaluated immediately.

Anyways, CSMongo is still early in development so if anyone has some additional ideas how to handle these updates then I'm certainly interested in what you think.

March 17, 2010

Performing Updates With CSMongo

Post titled "Performing Updates With CSMongo"