Hugoware

The product of a web developer with a little too much caffeine

Performing Updates With CSMongo

with 7 comments

I got some 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.

Written by hugoware

March 17, 2010 at 10:04 pm

7 Responses

Subscribe to comments with RSS.

  1. Great! You have done something pretty neat. I have been using the other C# driver for a while with great pain. I will definitely give it a try.

    Dave

    March 17, 2010 at 11:55 pm

  2. I’m working on a project that will allow WordPress bloggers a better way to link to songs on GrooveShark. Pushing the envelope here – CSMongo / Mono / Linux. I’ll keep you posted on my progress.

    Background on why I’m doing this:

    http://activeengine.wordpress.com/2010/03/05/clearspring-dumps-widgets-for-ad-revenue/

    ActiveEngine Sensei

    March 28, 2010 at 2:32 pm

    • I read that blog post wasn’t sure exactly what you were dealing with :)

      I’m interested to see what you come up with for your code. Make sure to ping me once you want some reviewers.

      hugoware

      March 28, 2010 at 9:24 pm

      • This is working great so far – clean compiles, creates and updates docs like a charm.

        For now I am using the driver in a DAL, but the flexibility that the Anonymous Method object you’ve implemented is screaming at me “let me in the Domain!”. From the perspective that different conditions will dictate different different attributes for documents, it doesn’t make sense to me that I should have UserRespository receive a DTO and I just do the update. I think I need to develop different instincts.

        To explain my post better, the ClearSpring widgets WERE a nice way to include a song in a blog post. Those blue boxes that you see in some of my post will play a song from GrooveShark. It was free, and really cool. ClearSpring is dropping the entire widget platform, and WordPress does not allow you to include ‘s in your post, so essentially you can’t have music in your posts. ClearSpring has a widget that will go in the side bar, but essentially be seen as an add, and not specific to post topics. My goal is provide a work around in html using GrooveShark’s API.

        Anyway, thanks again for creating good software – you’ve really kept me productive. When I get further along I’ll be posting and give the cred’s. I think you’re on to something really great.

        ActiveEngine Sensei

        March 29, 2010 at 6:41 am

  3. Great! I just completed running some sample code and it works just fine. I however noticed that there is currently no support for push and pull to add to and take from an array. Is it something in the pipeline? I’m looking at a scenario where you have a document which contains an array with a long list and instead of pulling the entire document, the push or pull could be used to update it.

    var doc = new MongoDocument();
    doc += new { firstname = “Mike”, surname = “Something”, dateOfEntry = DateTime.Now };
    doc.Set(“languages.programming”, new[] { “C#”, “C++” });

    //at some other time
    doc.push(“languages.programming”,”F#”).

    Richard

    April 26, 2010 at 2:37 am

    • As part of my test, I added the following to your code:
      Push,PushAll,Pull,PullAll,Pop,AddToSet and AddAllToSet. How can I share this if you’ve not already added them. Still exploring the mongo db. Great so far.

      Richard

      April 26, 2010 at 3:49 pm

      • Wow – that was fast… I haven’t even had a chance to look at the solution and you’ve already implemented it :)

        Yes, I’d love to see what you came up with – You can use the contact for on my site and we can get in contact. Thanks!

        hugoware

        April 26, 2010 at 3:55 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: