<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Captain Codeman&#187; cqrs</title>
	<atom:link href="http://www.captaincodeman.com/tag/cqrs/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.captaincodeman.com</link>
	<description>Software Developer</description>
	<lastBuildDate>Fri, 15 Jul 2011 22:50:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>Error with Azure local development storage and table named &#8216;event&#8217;</title>
		<link>http://www.captaincodeman.com/2010/06/30/error-azure-local-development-storage-table-named-event/</link>
		<comments>http://www.captaincodeman.com/2010/06/30/error-azure-local-development-storage-table-named-event/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 01:53:34 +0000</pubDate>
		<dc:creator>Captain Codeman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[azure]]></category>
		<category><![CDATA[cqrs]]></category>
		<category><![CDATA[table]]></category>

		<guid isPermaLink="false">http://www.captaincodeman.com/?p=217</guid>
		<description><![CDATA[While working on an Azure event-sourcing provider for my CQRS framework I came across a really strange problem so I&#8217;m posting the details in-case anyone else comes across a similar issue so they can save wasting as much time on it as I did! Basically, the local development storage doesn&#8217;t seem to like you having


No related posts.]]></description>
			<content:encoded><![CDATA[<p>While working on an Azure event-sourcing provider for my CQRS framework I came across a really strange problem so I&#8217;m posting the details in-case anyone else comes across a similar issue so they can save wasting as much time on it as I did! Basically, the local development storage doesn&#8217;t seem to like you having a table called &#8216;event&#8217; (I haven&#8217;t tested it on the live system).</p>
<p>Here is some test code to demonstrate the behavior:</p>
<pre class="brush:csharp">class Program
{
    static void Main(string[] args)
    {
        const string tableName = "test";
        var storageAccount = CloudStorageAccount.DevelopmentStorageAccount;

        var tableClient = storageAccount.CreateCloudTableClient();
        tableClient.CreateTableIfNotExist(tableName);

        var dataContext = tableClient.GetDataServiceContext();

        var bobdylan = new Artist
            {
                PartitionKey = "folk",
                RowKey = "bob-dylan",
                Name = "Bob Dylan"
            };

        dataContext.AddObject(tableName, bobdylan);
        dataContext.SaveChanges();
    }
}

[DataServiceKey("PartitionKey", "RowKey")]
public class Artist
{
    public virtual String PartitionKey { get; set; }
    public virtual String RowKey { get; set; }
    public DateTime Timestamp { get; set; }
    public string Name { get; set; }
}</pre>
<p>With the table called &#8216;test&#8217; in the example shown everything works fine and the table and data appear in the storage explorer:</p>
<p><a href="http://www.captaincodeman.com/?attachment_id=214" rel="attachment wp-att-214"><img src="http://www.captaincodeman.com/wp-content/uploads/2010/06/azure-table-working.png" alt="" title="azure-table-working" width="647" height="196" class="alignnone size-full wp-image-214" /></a></p>
<p>If we change the table name to &#8220;event&#8221; though we&#8217;ll get a DataServiceRequestException raised when we attempt to save changes:</p>
<p><a href="http://www.captaincodeman.com/2010/06/30/error-azure-local-development-storage-table-named-event/azure-table-error/" rel="attachment wp-att-218"><img src="http://www.captaincodeman.com/wp-content/uploads/2010/06/azure-table-error.png" alt="" title="azure-table-error" width="651" height="286" class="alignnone size-full wp-image-218" /></a></p>
<p>Strangely, the table <strong><em>does</em></strong> get created OK but just won&#8217;t let you save anything into it. I originally thought this may be an issue with a SQL reserved word (because the development storage is simulated using a SQL database) but I&#8217;m not sure this is the actual cause.</p>
<p>I guess I can&#8217;t have an &#8216;event&#8217; table like I wanted and will have to settle for &#8216;events&#8217; instead!</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.captaincodeman.com/2010/06/30/error-azure-local-development-storage-table-named-event/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running MongoDb on Microsoft Windows Azure with CloudDrive</title>
		<link>http://www.captaincodeman.com/2010/05/24/mongodb-azure-clouddrive/</link>
		<comments>http://www.captaincodeman.com/2010/05/24/mongodb-azure-clouddrive/#comments</comments>
		<pubDate>Tue, 25 May 2010 04:38:17 +0000</pubDate>
		<dc:creator>Captain Codeman</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[azure]]></category>
		<category><![CDATA[clouddrive]]></category>
		<category><![CDATA[cqrs]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[nosql]]></category>

		<guid isPermaLink="false">http://www.captaincodeman.com/?p=162</guid>
		<description><![CDATA[I&#8217;ve been playing around with the whole CQRS approach and think MongoDb works really well for the query side of things. I also figured it was time I tried Azure so I had a look round the web to see if there we&#8217;re instructions on how to run MongoDb on Microsoft&#8217;s Azure cloud. It turned out


No related posts.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing around with the whole CQRS approach and think <a href="http://www.mongodb.org/">MongoDb</a> works really well for the query side of things. I also figured it was time I tried Azure so I had a look round the web to see if there we&#8217;re instructions on how to run MongoDb on <a href="http://www.microsoft.com/windowsazure/">Microsoft&#8217;s Azure cloud</a>. It turned out there were only a few mentions of it or a general approach that should work but no detailed instructions on how to do it. So, I figured I&#8217;d give it a go and for a total-Azure-newbie it didn&#8217;t turn out to be too difficult.</p>
<p><a rel="attachment wp-att-165" href="http://www.captaincodeman.com/2010/05/24/mongodb-azure-clouddrive/windows-azure-logo-lg/"><img class="alignnone size-full wp-image-165" style="margin-left: 20px; margin-right: 20px;" title="windows-azure-logo-lg" src="http://www.captaincodeman.com/wp-content/uploads/2010/05/windows-azure-logo-lg.png" alt="" width="359" height="75" /></a><a rel="attachment wp-att-164" href="http://www.captaincodeman.com/2010/05/24/mongodb-azure-clouddrive/logo-mongodb-onwhite/"><img class="alignnone size-full wp-image-164" style="margin-left: 20px; margin-right: 20px;" title="logo-mongodb-onwhite" src="http://www.captaincodeman.com/wp-content/uploads/2010/05/logo-mongodb-onwhite.png" alt="" width="225" height="75" /></a></p>
<p>Obviously you&#8217;ll need an Azure account which you may get with MSDN or you can sign-up for their &#8216;free&#8217; account which has a limited number of hours included before you have to start paying. One thing to be REALLY careful of though &#8211; just deploying an app to Azure starts the clock running and leaving it deployed but turned off counts as hours so be sure to delete any experimental deployments you make after trying things out!!</p>
<p>First of all though it&#8217;s important to understand where MongoDb would fit with Azure. Each web or worker role runs as a virtual machine which has an amount of local storage included depending on the size of the VM, currently the four pre-defined VMs are:</p>
<div id="_mcePaste">
<ul>
<li><strong>Small</strong>: 1 core processor, 1.7GB RAM, <span style="text-decoration: underline;">250GB hard disk</span></li>
<li><strong>Medium</strong>: 2 core processors, 3.5GB RAM, <span style="text-decoration: underline;">500GB hard disk</span></li>
<li><strong>Large</strong>: 4 core processors, 7GB RAM, <span style="text-decoration: underline;">1000GB hard disk</span></li>
<li><strong>Extra Large:</strong> 8 core processors, 15GB RAM, <span style="text-decoration: underline;">2000GB hard disk</span></li>
</ul>
</div>
<p>This local storage is <em><strong>only temporary</strong></em> though and while it can be used for processing by the role instance running it isn&#8217;t available to any others and when the instance is moved, upgraded or recycled then it is lost forever (as in, gone for good).</p>
<p>For permanent storage Azure offers SQL-type databases (which we&#8217;re not interested in), Table storage (which would be an alternative to MongoDb but harder to query and with more limitations) and Blob storage.</p>
<p>We&#8217;re interested in Blob storage or more specifically Page-Blobs which support random read-write access &#8230; just like a disk drive. In fact, almost exactly like a disk drive because Azure provides a new CloudDrive which uses a VHD drive image stored as a Page-Blob (so it&#8217;s permanent) and can be mounted as a disk-drive within an Azure role instance.</p>
<p>The VHD images can range from 16Mb to 1Tb and apparently you only pay for the storage that is actually used, not the zeroed-bytes (although I haven&#8217;t tested this personally).</p>
<p>So, let&#8217;s look at the code to create a CloudDrive, mount it in an Azure worker role and run MongoDb as a process that can use the mounted CloudDrive for it&#8217;s permanent storage so that everything is kept between machine restarts. We&#8217;ll also create an MVC role to test direct connectivity to MongoDb between the two VMs using internal endpoints so that we don&#8217;t incur charges for Queue storage or Service Bus messages.</p>
<p>The first step is to create a &#8216;Windows Azure Cloud Service&#8217; project in Visual Studio 2010 and add both an MVC 2 and Worker role to it.</p>
<p>We will need a copy of the mongod.exe to include in the worker role so just drag and drop that to the project and set it to be Content copied when updated. Note that the Azure VMs are 64-bit instances so you need the 64-bit Windows version of MongoDb.</p>
<p><a rel="attachment wp-att-176" href="http://www.captaincodeman.com/2010/05/24/mongodb-azure-clouddrive/mongod-exe/"><img class="alignnone size-full wp-image-176" title="mongod-exe" src="http://www.captaincodeman.com/wp-content/uploads/2010/05/mongod-exe.png" alt="" width="232" height="479" /></a></p>
<p>We&#8217;ll also need to add a reference to the .NET MongoDb client library to the web role. I&#8217;m using the <a href="http://github.com/samus/mongodb-csharp">mongodb-csharp</a> one but you can use one of the others if you prefer.</p>
<p>Our worker role needs a connection to the Azure storage account which we&#8217;re going to call &#8216;MongDbData&#8217;</p>
<p><a rel="attachment wp-att-181" href="http://www.captaincodeman.com/2010/05/24/mongodb-azure-clouddrive/settings-mongodbdata/"><img class="alignnone size-full wp-image-181" title="settings-mongoDbData" src="http://www.captaincodeman.com/wp-content/uploads/2010/05/settings-mongoDbData.png" alt="" width="766" height="314" /></a></p>
<p>The other configured setting that we need to define is some local storage allocated as a cache for use with the CloudDrive, we&#8217;ll call this &#8216;MongoDbCache&#8217;. For this demo we&#8217;re going to create a 4Gb cache which will match the 4Gb drive we&#8217;ll create for MongoDb data. I haven&#8217;t played enough to evaluate performance yet but from what I understand this cache acts a little like the write-cache that you can turn on for your local hard drive.</p>
<p><a rel="attachment wp-att-182" href="http://www.captaincodeman.com/2010/05/24/mongodb-azure-clouddrive/settings-mongodbcache/"><img class="alignnone size-full wp-image-182" title="settings-mongoDbCache" src="http://www.captaincodeman.com/wp-content/uploads/2010/05/settings-mongoDbCache.png" alt="" width="763" height="309" /></a></p>
<p>The last piece before we can crack on with some coding is to define an endpoint which is how the Web Role / MVC App will communicate with the MongoDb server on the Worker Role. This basically tells Azure that we&#8217;d like an IP Address and a port to use and it makes sure that we can use it and no one else can. It should be possible to make the endpoint public to the world if you wanted but that isn&#8217;t the purpose of this demo. The endpoint is called &#8216;MongoDbEndpoint&#8217; and set to Internal / TCP:</p>
<p><a rel="attachment wp-att-183" href="http://www.captaincodeman.com/2010/05/24/mongodb-azure-clouddrive/settings-mongodbendpoint/"><img class="alignnone size-full wp-image-183" title="settings-mongoDbEndpoint" src="http://www.captaincodeman.com/wp-content/uploads/2010/05/settings-mongoDbEndpoint.png" alt="" width="764" height="311" /></a></p>
<p>Now for the code and first we&#8217;ll change the WorkerRole.cs file in the WorkerRole1 project (as you can see, I put a lot of effort into customizing the project names!). We&#8217;re going to need to keep a reference to the CloudDrive that we&#8217;re mounting and also the MongoDb process that we&#8217;re going to start so that we can shut them down cleanly when the instance is stopping:</p>
<pre class="brush:csharp">private CloudDrive _mongoDrive;
private Process _mongoProcess;</pre>
<p>In the OnStart() method I&#8217;ve added some code copied from the Azure SDK Thumbnail sample &#8211; this prepares the CloudStorageAccount configuration so that we can use the method CloudStorageAccount.FromConfigurationSetting() to load the details from configuration (this just makes it easier to switch to using the Dev Fabric on our local machine without changing code). I&#8217;ve also added a call to StartMongo() and created an OnStop() method which simply closes the MongoDb process and unmounts the CloudDrive when the instance is stopping:</p>
<pre class="brush:csharp">public override bool OnStart()
{
    // Set the maximum number of concurrent connections
    ServicePointManager.DefaultConnectionLimit = 12;

    DiagnosticMonitor.Start("DiagnosticsConnectionString");

    #region Setup CloudStorageAccount Configuration Setting Publisher

    // This code sets up a handler to update CloudStorageAccount instances when their corresponding
    // configuration settings change in the service configuration file.
    CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =&gt;
    {
        // Provide the configSetter with the initial value
        configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

        RoleEnvironment.Changed += (sender, arg) =&gt;
        {
            if (arg.Changes.OfType()
                .Any((change) =&gt; (change.ConfigurationSettingName == configName)))
            {
                // The corresponding configuration setting has changed, propagate the value
                if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
                {
                    // In this case, the change to the storage account credentials in the
                    // service configuration is significant enough that the role needs to be
                    // recycled in order to use the latest settings. (for example, the
                    // endpoint has changed)
                    RoleEnvironment.RequestRecycle();
                }
            }
        };
    });
    #endregion

    // For information on handling configuration changes
    // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
    RoleEnvironment.Changing += RoleEnvironmentChanging;

    StartMongo();

    return base.OnStart();
}

public override void OnStop()
{
    _mongoProcess.Close();
    _mongoDrive.Unmount();

    base.OnStop();
}</pre>
<p>Next is the code to create the CloudDrive and start the MongoDb process running:</p>
<pre class="brush:csharp">private void StartMongo()
{
    // local cache drive we'll use on the CM
    LocalResource localCache = RoleEnvironment.GetLocalResource("MongoDbCache");

    Trace.TraceInformation("MongoDbCache {0} {1}", localCache.RootPath, localCache.MaximumSizeInMegabytes);
    // we'll use all the cache space we can (note: InitializeCache doesn't work with trailing slash)
    CloudDrive.InitializeCache(localCache.RootPath.TrimEnd('\\'), localCache.MaximumSizeInMegabytes);

    // connect to the storage account
    CloudStorageAccount storageAccount = CloudStorageAccount.FromConfigurationSetting("MongoDbData");

    // client for talking to our blob files
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

    // the container that our dive is going to live in
    CloudBlobContainer drives = blobClient.GetContainerReference("drives");

    // create blob container (it has to exist before creating the cloud drive)
    try {drives.CreateIfNotExist();} catch {}

    // get the url to the vhd page blob we'll be using
    var vhdUrl = blobClient.GetContainerReference("drives").GetPageBlobReference("MongoDb.vhd").Uri.ToString();
    Trace.TraceInformation("MongoDb.vhd {0}", vhdUrl);

    // create the cloud drive
    _mongoDrive = storageAccount.CreateCloudDrive(vhdUrl);
    try
    {
        _mongoDrive.Create(localCache.MaximumSizeInMegabytes);
    }
    catch (CloudDriveException ex)
    {
        // exception is thrown if all is well but the drive already exists
    }

    // mount the drive and get the root path of the drive it's mounted as
    var dataPath = _mongoDrive.Mount(localCache.MaximumSizeInMegabytes, DriveMountOptions.Force) + @"\";
    Trace.TraceInformation("Mounted as {0}", dataPath);

    // get the internal enpoint that we're going to use for MongoDb
    var ep = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["MongoDbEndpoint"];

    // create the process to host mongo
    _mongoProcess = new Process();
    var startInfo = _mongoProcess.StartInfo;
    // so we can redirect streams
    startInfo.UseShellExecute = false;
    // we don't need a window, it's hard to see the monitor from here (jk)
    startInfo.CreateNoWindow = false;
    // the mongo daemon is included in our project in the current directory
    startInfo.FileName = @"mongod.exe";
    startInfo.WorkingDirectory = Environment.CurrentDirectory;
    // specify the ip address and port for MongoDb to use and also the path to the data
    startInfo.Arguments = string.Format(@"--bind_ip {0} --port {1} --dbpath {2} --quiet", ep.IPEndpoint.Address, ep.IPEndpoint.Port, dataPath);
    // capture mongo output to Azure log files
    startInfo.RedirectStandardError = true;
    startInfo.RedirectStandardOutput = true;
    _mongoProcess.ErrorDataReceived += (sender, evt) =&gt; WriteLine(evt.Data);
    _mongoProcess.OutputDataReceived += (sender, evt) =&gt; WriteLine(evt.Data);

    Trace.TraceInformation("Mongo Process {0}", startInfo.Arguments);

    // start mongo going
    _mongoProcess.Start();
    _mongoProcess.BeginErrorReadLine();
    _mongoProcess.BeginOutputReadLine();
}</pre>
<p>[TODO: Add more explanation !!]</p>
<p>So, that&#8217;s the server-side, oops, I mean Worker Role setup which will now run MongoDb and persist the data permanently. We could get fancier and have multiple roles with slave / sharded instances of MongoDb but they will follow a similar pattern.</p>
<p>The client-side in the Web Role MVC app is very simple and the only extra work we need to do is to figure out the IP Address and Port that we need to connect to MongoDb using which are setup for us by Azure. The RoleEnvironment lets us get to this and I believe (but could be wrong so don&#8217;t quote me) that the App Fabric part of Azure handles the communication between roles to pass this information. Once we have it we can create our connection to MongoDb as normal and save NoSQL JSON documents to our hearts content &#8230;</p>
<pre class="brush:csharp">var workerRoles = RoleEnvironment.Roles["WorkerRole1"];
var workerRoleInstance = workerRoles.Instances[0];
RoleInstanceEndpoint ep = workerRoleInstance.InstanceEndpoints["MongoDbEndpoint"];

string connectionString = string.Format("Server={0}:{1}", ep.IPEndpoint.Address, ep.IPEndpoint.Port);

var mongo = new Mongo(connectionString);
mongo.Connect();
var db = mongo.GetDatabase("notes");</pre>
<p>I hope you find this useful. I&#8217;ll try and add some extra notes to explain the code and the thinking behind it in more detail and will post some follow ups to cover deploying the app to Azure and what I&#8217;ve learned of that process.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.captaincodeman.com/2010/05/24/mongodb-azure-clouddrive/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Benefits of NoSQL (MongoDb) for the Query-side of CQRS</title>
		<link>http://www.captaincodeman.com/2010/04/11/benefits-nosql-mongodb-query-cqrs/</link>
		<comments>http://www.captaincodeman.com/2010/04/11/benefits-nosql-mongodb-query-cqrs/#comments</comments>
		<pubDate>Mon, 12 Apr 2010 02:31:26 +0000</pubDate>
		<dc:creator>Captain Codeman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cqrs]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[nhibernate]]></category>
		<category><![CDATA[nosql]]></category>

		<guid isPermaLink="false">http://www.captaincodeman.com/?p=158</guid>
		<description><![CDATA[As you may know I&#8217;ve been researching CQRS and the benefits of using this approach to developing systems. My focus at the moment is on the Query side of things and for this I&#8217;ve been comparing a SQL Server / NHibernate solution with a NoSQL alternative using MongoDb. For this, I&#8217;ve been using a simple forum


No related posts.]]></description>
			<content:encoded><![CDATA[<p>As you may know I&#8217;ve been researching CQRS and the benefits of using this approach to developing systems. My focus at the moment is on the Query side of things and for this I&#8217;ve been comparing a SQL Server / NHibernate solution with a NoSQL alternative using MongoDb. For this, I&#8217;ve been using a simple forum app that I&#8217;ve been working on with a database of around 4m posts and 200k topics.</p>
<p>I&#8217;ll post more detailed results when I have time to show things in more detail (with some example code) but basically, the performance difference I&#8217;ve been seeing is huge.</p>
<p>The SQL Server / NHibernate solution was generating about 10 requests per second and had SQL Server at about 50% of the CPU. The MongoDB backed solution was running at around 50 requests per second and MongoDb was sat at around 3-4% of CPU time.</p>
<p>Right now, I&#8217;m very excited about the possibilities of improving app performance (especially now that Google are taking this into account when calculating page-rank) but also, the difference in the complexity of the code between the two systems is also refreshing with the MongoDb solution very, very simple and quick to develop.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.captaincodeman.com/2010/04/11/benefits-nosql-mongodb-query-cqrs/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Circles of Interest</title>
		<link>http://www.captaincodeman.com/2010/03/31/circles-interest/</link>
		<comments>http://www.captaincodeman.com/2010/03/31/circles-interest/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 19:05:02 +0000</pubDate>
		<dc:creator>Captain Codeman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[cqrs]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[lucene]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[nosql]]></category>

		<guid isPermaLink="false">http://www.captaincodeman.com/?p=151</guid>
		<description><![CDATA[Technologies that I'm interested in and passionate about vs those that ... well, not so much


No related posts.]]></description>
			<content:encoded><![CDATA[<p>I saw this on another blog and thought it was a neat way of showing the technologies that I am interested in or indifferent to.</p>
<h2><span style="color: #339966;">Positive / Core</span></h2>
<p>Things I care about or am interested in learning:</p>
<ul>
<li>ASP.NET MVC</li>
<li>HTML5 / CSS3</li>
<li>jQuery / JavaScript</li>
<li>DDDD / ESB / EDA / SOA / CQRS</li>
<li>Dependency Injection</li>
<li>Architecture</li>
<li>Lucene</li>
<li>Document Databases</li>
<li>Cloud Computing</li>
<li>User Interface Design</li>
<li>NoSQL data stores</li>
<li>MongoDB</li>
<li>Event Sourcing</li>
</ul>
<h2><span style="color: #3366ff;">Neutral / Non-core</span></h2>
<p>Things I care about but not as much or already know:</p>
<ul>
<li>ASP.NET WebForms</li>
<li>SQL Server</li>
<li>ETL</li>
<li>LINQ</li>
<li>AJAX, TDD</li>
<li>Source Control</li>
<li>WCF</li>
</ul>
<h2><span style="color: #993300;">Negative</span></h2>
<p>Things I don&#8217;t care about and have no particular interest or excitement in:</p>
<ul>
<li>Team System</li>
<li>Sharepoint</li>
<li>WPF</li>
<li>Silverlight</li>
<li>Flash</li>
<li>Windows</li>
<li>Office</li>
<li>Virtualization</li>
</ul>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.captaincodeman.com/2010/03/31/circles-interest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Homongous! MongoDB, NoSQL and CQRS</title>
		<link>http://www.captaincodeman.com/2010/03/31/homongous-mongodb-nosql-cqrs/</link>
		<comments>http://www.captaincodeman.com/2010/03/31/homongous-mongodb-nosql-cqrs/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 17:11:55 +0000</pubDate>
		<dc:creator>Captain Codeman</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[automapper]]></category>
		<category><![CDATA[cqrs]]></category>
		<category><![CDATA[cte]]></category>
		<category><![CDATA[fluentnhibernate]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[nhibernate]]></category>
		<category><![CDATA[ninject]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[object database]]></category>
		<category><![CDATA[rdbms]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://www.captaincodeman.com/?p=131</guid>
		<description><![CDATA[I&#8217;ve got what I consider to be a pretty good development stack &#8211; all the usual suspects: MVC for the front-end; data stored in SQL Server or MySQL and accessed via NHibernate with mappings using FluentNHibernate conventions; the domain model mapped to a view model using AutoMapper and a sprinkling of NInject dependency injection to


No related posts.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve got what I consider to be a pretty good development stack &#8211; all the usual suspects: <a href="http://www.asp.net/mvc/">MVC</a> for the front-end; data stored in <a href="http://www.microsoft.com/sqlserver/">SQL Server</a> or <a href="http://www.mysql.com/">MySQL</a> and accessed via <a href="http://nhforge.org/">NHibernate</a> with mappings using <a href="http://fluentnhibernate.org/">FluentNHibernate</a> conventions; the domain model mapped to a view model using <a href="http://automapper.codeplex.com/">AutoMapper</a> and a sprinkling of <a href="http://ninject.org/">NInject</a> dependency injection to tie it all together without direct dependencies.</p>
<p>And of course it works, it&#8217;s proven &#8211; lots of people use this approach. Lately though I&#8217;ve been reading a lot about different architectural approaches and in particular <a href="http://www.udidahan.com/2009/12/09/clarified-cqrs/">CQRS</a> or &#8216;<a href="http://elegantcode.com/2009/11/11/cqrs-la-greg-young/">Command Query Responsibility Segregation</a>&#8216; from <a href="http://www.udidahan.com/?blog=true">Udi Dahan</a> and <a href="http://codebetter.com/blogs/gregyoung/">Greg Young</a> which, among other things, promotes the idea of having a separate denormalized repository for querying data and another, possibly normalized relational database, for writing to.</p>
<p>Because the query-side repository is denormalized it really lends itself to using a <a href="http://en.wikipedia.org/wiki/NoSQL">NoSQL approach</a> which seems to be gaining ground so I thought I&#8217;d give it a try to see how well it would work using a forum app I&#8217;ve been re-developing (currently an MVC/NHibernate/SQL Server based app).</p>
<p>Now, it&#8217;s not facebook but it&#8217;s not trivial either &#8211; there are about 4m posts spread over 200k topics and I&#8217;ve done quite a bit of work on the database side of things to make sure it&#8217;s efficient and normalized. One feature I&#8217;m implementing is to go away from the old and boring topic list that most forums have (where they show the topic title, author, date, number of replies and sometimes the date and author of the latest reply) and present it more graphically with the avatar of the topic starter, the title, date and folder it&#8217;s in and then the avatars of the last 3 or more (depending on configuration) people who have replied. Here&#8217;s an example:</p>
<p><a rel="attachment wp-att-132" href="http://www.captaincodeman.com/2010/03/31/homongous-mongodb-nosql-cqrs/topic-summary/"><img class="alignnone size-full wp-image-132" title="topic-summary" src="http://www.captaincodeman.com/wp-content/uploads/2010/03/topic-summary.png" alt="" width="600" height="60" /></a></p>
<p>Now, to do this with the relational model means that I need to do quite a few table joins and when there are 4m+ rows that I need to be able to sort and page over it can start to chug a little. So, to speed things up I&#8217;ve spent some time optimizing the queries to use <a href="http://msdn.microsoft.com/en-us/library/cc917715.aspx">Indexed Views</a> to combine the Topic, Folder and Author and <a href="http://msdn.microsoft.com/en-us/library/ms190766.aspx">Common Table Expressions (CTE)</a> to get the last 3 replies which means joining the Topic, Post and Author tables again. It all works and it&#8217;s pretty quick but it&#8217;s been a lot of work to get it to that point.</p>
<p>So, the first test was to pick a NoSQL database to try as an alternative. I read up on quite a few and looked at the features and compatibility with Windows/C#/.NET including <a href="http://couchdb.apache.org/">CouchDB</a>, <a href="http://www.mongodb.org/">MongoDB</a>, <a href="http://cassandra.apache.org/">Cassandra</a>, <a href="http://project-voldemort.com/">Voldemort </a>and <a href="http://nosql-database.org/">others</a> and in the end decided to go with MongoDB.</p>
<p><a href="http://www.mongodb.org/display/DOCS/Quickstart">Downloading and installing MongoDB</a> (basically just unzipping the files) was easy and with the excellent documentation I was up and running really quickly and ready to start trying things out.</p>
<p>The first step was to try reading and writing documents using C# and this was really straightforward using the <a href="http://www.mongodb.org/display/DOCS/C+Sharp+Language+Center">mongodb-csharp driver</a>. So, next step was to convert the data from SQL Server into it. I already had the queries that created the paged views of data &#8211; typically with 10 or 20 records per page and thought I&#8217;d just re-use that. Running against the whole recordset really slowed it down though but after SQL Server chugged away for 10 or 15 minutes and used 6.5Gb of RAM it managed to give me the data and I created the <a href="http://www.json.org/">JSON</a> documents in-memory ready for inserting.</p>
<p>So, I call &#8216;Insert&#8217; to add the collection of documents to the MongoDB store. And it failed. Well, actually &#8230; I assumed it failed because it only seemed to take about 5 seconds and my console app finished. When I went to the MongoDB console and queried the data though it was all there &#8230; and I could query it, sort it, page through it, very VERY quickly &#8211; much quicker than using SQL Server and the relational model. Windows process explorer showed MongoDB used just a few Mb of RAM to do this.</p>
<p>Because querying was so easy and so direct I no longer needed to use an OR/M to address the <a href="http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch">object-relational impedance mismatch</a> (a fancy way of saying an RDBMS sucks for OO) and I no longer needed to transform the persistent domain model into a view model before presenting it. I can just get the view model objects straight from the store and render them. Fast, simple, and I get to delete lots of code which is kind of soul destroying when you&#8217;ve written it but I&#8217;m excited at all the code I won&#8217;t have to write in future with this approach and the performance.</p>
<p>MongoDB is very, very fast and very easy to use although it requires a slightly different way of thinking when you&#8217;re more used to working with a relational model. One of the big selling points is that it&#8217;s easier to scale than a relational system and while I didn&#8217;t try the sharding support (which is in alpha) I did give the replication a go &#8211; again, it was much easier to setup than the equivalent would be with SQL Server and it performed very well.</p>
<p>Finally, I did a few more experiments to test the insert performance compared to SQL Server and basically setup a simple table with an Id, Name and Number column and inserted 500,000 rows. I used parameterized queries for SQL Server, re-used the same command object and wrapped it all in a single transaction but it took over 55 seconds to run (plus I had to create the database and table in advance which took a minute or two). Doing the same thing with MongoDB ran in under 10 seconds and the client code was much simpler and I didn&#8217;t have any initial setup.</p>
<p>I&#8217;m definitely going to explore MongoDB more and plan on making use of it in future projects when it&#8217;s appropriate. The next piece to look at is the Command side of CQRS where I want to use <a href="http://codebetter.com/blogs/gregyoung/archive/2010/02/20/why-use-event-sourcing.aspx">event sourcing for storage</a> and an event driven / service oriented architecture and better domain driven design techniques.</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.captaincodeman.com/2010/03/31/homongous-mongodb-nosql-cqrs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

