<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>The MongoDB NoSQL Database Blog</title><generator>Tumblr (3.0; @mongodb)</generator><link>http://blog.mongodb.org/</link><item><title>MongoDB Driver Releases: April </title><description>&lt;p&gt;&lt;strong&gt;&lt;span&gt;We&amp;#8217;ve had a big month with updates and improvements to our drivers.  Here’s a summary:&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;span&gt;We released v1.0 of the &lt;/span&gt;&lt;a href="https://github.com/mongodb/mongo-hadoop"&gt;&lt;span&gt;Mongo-Hadoop connector&lt;/span&gt;&lt;/a&gt;&lt;span&gt;, which provides working input and output adapters for MongoDB on &lt;/span&gt;&lt;a href="http://hadoop.apache.org/mapreduce/"&gt;&lt;span&gt;Hadoop&amp;#8217;s MapReduce&lt;/span&gt;&lt;/a&gt;&lt;span&gt;. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;We released &lt;/span&gt;&lt;a href="https://github.com/mongodb/node-mongodb-native"&gt;&lt;span&gt;Node.js Driver&lt;/span&gt;&lt;/a&gt;&lt;span&gt; v1.0.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Aaron Heckmann made a bunch of bug fixes and feature updates to &lt;/span&gt;&lt;a href="https://github.com/learnboost/mongoose"&gt;&lt;span&gt;Mongoose 2.6.x&lt;/span&gt;&lt;/a&gt;&lt;span&gt; &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;The &lt;/span&gt;&lt;a href="http://api.mongodb.org/csharp/current/"&gt;&lt;span&gt;1.4 release&lt;/span&gt;&lt;/a&gt;&lt;span&gt; of the C# Driver now supports LINQ queries.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;The 1.6.2 release of the &lt;/span&gt;&lt;a href="http://api.mongodb.org/ruby/current/"&gt;&lt;span&gt;Ruby driver&lt;/span&gt;&lt;/a&gt;&lt;span&gt; now implements socket timeout using non-blocking IO. This change improve performance when timeouts are enabled. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;There are a number of bug fixes in the &lt;/span&gt;&lt;a href="http://us2.php.net/mongo"&gt;&lt;span&gt;PHP driver&amp;#8217;s&lt;/span&gt;&lt;/a&gt;&lt;span&gt; 1.2.10 release&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;The PyMongo team pushed &lt;/span&gt;&lt;a href="http://api.mongodb.org/python/current/"&gt;&lt;span&gt;PyMongo 2.2&lt;/span&gt;&lt;/a&gt;&lt;span&gt;, which has support for &lt;/span&gt;&lt;a href="http://api.mongodb.org/python/current/python3.html"&gt;&lt;span&gt;Python 3&lt;/span&gt;&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a href="http://api.mongodb.org/python/current/examples/gevent.html"&gt;&lt;span&gt;Gevent&lt;/span&gt;&lt;/a&gt;&lt;span&gt; and &lt;/span&gt;&lt;a href="http://api.mongodb.org/python/current/examples/requests.html"&gt;&lt;span&gt;improved pooling&lt;/span&gt;&lt;/a&gt;&lt;span&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.mongodb.org/post/22638600720</link><guid>http://blog.mongodb.org/post/22638600720</guid><pubDate>Tue, 08 May 2012 01:01:38 -0400</pubDate><category>MongoDB</category><category>drivers</category><category>python</category><category>node.js</category><category>hadoop</category><category>mapreduce</category><category>mongoose</category><category>ruby</category><category>php</category><category>pymongo</category><category>nosql</category></item><item><title>MongoDB at Craigslist: 1 Year Later </title><description>&lt;p&gt;&lt;em&gt;Update: watch &lt;strong&gt;&lt;a href="http://www.10gen.com/presentations/mongosf-2012/mongodb-at-craigslist-one-year-later"&gt;the video&lt;/a&gt;&lt;/strong&gt; of Jeremy Zawodny and Chris Mooney&amp;#8217;s talk on &lt;strong&gt;&lt;a href="http://www.10gen.com/presentations/mongosf-2012/mongodb-at-craigslist-one-year-later"&gt;A Year of MongoDB at Craigslist&lt;/a&gt; &lt;/strong&gt;at MongoSF &amp;#8216;12&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Last year, Craigslist moved their archive &lt;a href="http://blog.mongodb.org/post/5545198613/mongodb-live-at-craigslist"&gt;to MongoDB from MySQL&lt;/a&gt;. After the initial set up, we spoke with Jeremy Zawodny, software engineer at Craigslist and the author of &lt;em&gt;&lt;a href="http://shop.oreilly.com/product/9780596101718.do"&gt;High Performance MySQL&lt;/a&gt; (O&amp;#8217;Reilly)&lt;/em&gt;, &lt;a href="http://blog.mongodb.org/page/2"&gt;and asked him some questions about their cluster&lt;/a&gt;. In advance of their talk at &lt;a href="http://mongosf.com"&gt;MongoSF&lt;/a&gt; tomorrow, we caught up with Jeremy to get the scoop on what&amp;#8217;s happening at Craigslist one year later. &lt;/p&gt;
&lt;p&gt;&lt;em&gt;Last time we spoke you were building a MongoDB store for 5 Billion Documents. What do your numbers look like now? &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We&amp;#8217;re currently approaching the 3 billion mark. The 5 billion number was our target capacity when building the system. Back then we had &lt;a href="http://www.10gen.com/customers/craigslist"&gt;about 2.5 billion documents&lt;/a&gt; that we migrated into MongoDB, and we&amp;#8217;ve continued to add documents ever since then.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Can you share an anecdote on the benefits of replica sets/sharding and something you&amp;#8217;d like to change/improve in that feature set? &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The sharding has made it easy for handling growth. We know that when the day comes, we can add an additional replica set to our cluster and it will help ease any space crunch. The replica sets have been great for handling machine failures. We&amp;#8217;ve had several machines lock-up on us and require unplanned reboots or service. Throughout that time, the worst thing we&amp;#8217;ve seen is some read-only time for the cluster metadata (when a config server dropped) but we&amp;#8217;ve been able to serve requests without stopping.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Can you share some anecdotes about how your team adjusted to working with MongoDB? &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There was a bit of adjustment that our systems administration team performed to the original deployment and configuration to make it better mesh with our home-grown management and deployment tools. But other than that, MongoDB has been pretty hands-off for most of the team. As long as it behaves well (which it does), we don&amp;#8217;t need to touch it that often.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Any exciting plans for your MongoDB clusters?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ve been testing MongoDB in a few new roles at Craigslist and plan to present some of those challenges at &lt;a href="http://mongosf.com"&gt;MongoSF&lt;/a&gt; on May 4th. &lt;/p&gt;
&lt;p&gt;&lt;em&gt;Thanks to Jeremy for giving us some insight into how MongoDB powers Craigslist! &lt;/em&gt;&lt;/p&gt;</description><link>http://blog.mongodb.org/post/22327647691</link><guid>http://blog.mongodb.org/post/22327647691</guid><pubDate>Thu, 03 May 2012 13:38:00 -0400</pubDate></item><item><title>MongoDB: Powering the Magic and the Monsters at Stripe</title><description>&lt;p&gt;&lt;a href="https://stripe.com/"&gt;&lt;img align="left" height="185" src="https://stripe.com/img/frontpage/blueprints.png" width="220"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update: Watch the video of Greg Brockman&amp;#8217;s talk on &lt;a href="http://www.10gen.com/presentations/mongosf-2012/high-availability-with-mongodb-for-fun-and-profit"&gt;MongoDB for High Availability&lt;/a&gt; at MongoSF &amp;#8216;12&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stripe.com/"&gt;Stripe&lt;/a&gt; offers a simple platform for developers to accept online payments. They are a long-time user of MongoDB and have built a powerful and flexible system for enabling transactions on the web. In advance of their talk at MongoSF on MongoDB for high availability, Stripe’s engineer, &lt;a href="http://twitter.com/thegdb"&gt;Greg Brockman&lt;/a&gt; spoke with us about what’s going on with MongoDB at Stripe.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Stripe has a heavy write load with large query volumes. Can you give us some insight into your tips and tricks for wrangling with MongoDB&amp;#8217;s replica sets on your system?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Getting replica sets up and running is actually incredibly easy. I used to run MySQL clusters where configuring and maintaining replication was a pain, and it was a joy to just be able to run &amp;#8220;rs.add(node)&amp;#8221; and watch it join the cluster.&lt;/p&gt;
&lt;p&gt;In order to avoid losing any operations even if we lose our database primary, we structure our application such that all writes are idempotent. We then wrap our calls to the MongoDB driver in a retry block. If the call fails because our MongoDB cluster is currently reconfiguring, we try the operation again (with the usual backoff and timeout you&amp;#8217;d expect from a scheme like this). We&amp;#8217;re very careful to avoid operations which could result in evicting hot data from the cache. Running unindexed queries is an obvious example of this, but we&amp;#8217;ve also found that running a large multi-update can have production impact.&lt;/p&gt;
&lt;p&gt;So when we need to change our schema for an entire collection of documents, we&amp;#8217;ll usually run a slower (but non-impactful) document-by-document migration at the application level.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Let&amp;#8217;s take a step back to your past talk at MongoSV &amp;#8216;11 &amp;#8212; what are you doing with Monster (Stripe&amp;#8217;s native events processing system for payments)? &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.10gen.com/presentations/mongosv-2011/theres-a-monster-in-my-closet-architecture-of-a-mongodb-powered-event-processing-system"&gt;Monster&lt;/a&gt; is our framework for event production and event consumption, which uses MongoDB as a highly-available, persistent queue. With Monster, our engineers can start logging a new type of event with only a few lines of code, and at any time in the future can add a consumer that will automatically be passed relevant events (possibly even historical ones). We use it for a variety of purposes: structured logging, incremental updating of state (such as people&amp;#8217;s graphs of payment volume), and background jobs.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Lots of people are innovating in the financial space &amp;#8212; in particular building APIs for mobile payments. For those just starting up, why should they use MongoDB? &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As a payments processor, our uptime is incredibly important. We were initially drawn to MongoDB because replica sets make it incredibly easy to run your database in a highly-available fashion. I came from a world where my database master could never be rebooted, since there was no zero-downtime failover strategy even for routine maintenance &amp;#8212; MongoDB gives you this almost out of the box.&lt;/p&gt;
&lt;p&gt;MongoDB also makes it easy to do zero-downtime migrations, with features such as background index builds and allowing multiple schemas in a single collection. Anyone caring about their availability should look very hard at MongoDB.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;How are you guys using the Ruby driver in your system? Anything interesting? &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ve banged on the &lt;a href="http://api.mongodb.org/ruby/current/"&gt;Ruby driver&lt;/a&gt; in a variety of configurations, ensuring that it behaves properly when exposed to all the possible failures we can imagine (or have noticed) our database servers experiencing. These days, we&amp;#8217;re very happy with how robust the Ruby driver is against the wide variety of failure modes of the distributed MongoDB nodes.&lt;/p&gt;
&lt;p&gt;&lt;em&gt; What&amp;#8217;s your wish list for the Ruby Driver? &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I wish there were a configuration option for forcing reads from a secondary. (Right now, you can request that reads be on a secondary if one is available, but they&amp;#8217;ll start reading from the primary if no secondary is available.)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;What&amp;#8217;s on stripe&amp;#8217;s engineering roadmap? &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;While making Stripe available outside the US is our top priority, our biggest engineering challenges at the moment are scaling our systems to keep up with the phenomenal growth we&amp;#8217;ve been experiencing.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Many thanks to Greg for taking the time to tell a bit about the magic at Stripe.&lt;/em&gt;&lt;/p&gt;</description><link>http://blog.mongodb.org/post/22280693621</link><guid>http://blog.mongodb.org/post/22280693621</guid><pubDate>Wed, 02 May 2012 18:41:00 -0400</pubDate><category>mongodb</category><category>stripe</category><category>event-processing</category><category>mongosf</category><category>api</category><category>payments</category><category>finance</category><category>nosql</category></item><item><title>Revamp of MongoDB's Documentation</title><description>&lt;p&gt;We&amp;#8217;re revamping &lt;a href="http://docs.mongodb.org/manual/"&gt;MongoDB&amp;#8217;s documentation&lt;/a&gt;. The new design in the MongoDB Manual has an improved &lt;a href="http://docs.mongodb.org/manual/reference/"&gt;reference&lt;/a&gt; section and an &lt;a href="http://docs.mongodb.org/manual/genindex/"&gt;index&lt;/a&gt; for simplified search. It will also eventually support multiple MongoDB versions at the same time.&lt;/p&gt;
&lt;p&gt;This project is a work in progress, and things are changing quickly. Our goal is to consolidate, sharpen, organize, and continue to improve the documentation in support of MongoDB. For now, the new docs will live alongside the original MongoDB Wiki. But over the next few months, we&amp;#8217;ll be transitioning everything to the new manual.&lt;/p&gt;
&lt;p&gt;In the spirit of open source, the docs are housed on &lt;a href="https://github.com/mongodb/docs"&gt;Github&lt;/a&gt;. Feedback is welcome! Feel free to fork the repository and issue pull requests. You can also open tickets in &lt;a href="https://jira.mongodb.org/browse/DOCS"&gt;JIRA&lt;/a&gt;, and we&amp;#8217;ll promptly address any suggestions.&lt;/p&gt;</description><link>http://blog.mongodb.org/post/22199152764</link><guid>http://blog.mongodb.org/post/22199152764</guid><pubDate>Tue, 01 May 2012 12:59:19 -0400</pubDate><category>documentation</category><category>mongodb</category><category>open source</category><category>jira</category><category>github</category><category>release</category></item><item><title>Meet Variety, a Schema Analyzer for MongoDB</title><description>&lt;p&gt;Variety is a lightweight tool which gives a feel for an application&amp;#8217;s schema, as well as any schema outliers. It is particularly useful for&lt;/p&gt;
&lt;p&gt;• quickly learning how data is structured, if inheriting a codebase with a production data dump&lt;/p&gt;
&lt;p&gt;• finding all rare keys in a given collection&lt;/p&gt;
&lt;h4&gt;An Easy Example&lt;/h4&gt;
&lt;p&gt;We&amp;#8217;ll make a collection, within the MongoDB shell:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;db.users.insert({name: "Tom", bio: "A nice guy.", pets: ["monkey", "fish"], someWeirdLegacyKey: "I like Ike!"});
db.users.insert({name: "Dick", bio: "I swordfight."}); 
db.users.insert({name: "Harry", pets: "egret"});
db.users.insert({name: "Geneviève", bio: "Ça va?"}); &lt;/pre&gt;
&lt;p&gt;&lt;!-- more --&gt;Let&amp;#8217;s use Variety on this collection, and see what it can tell us:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;$ mongo test --eval "var collection = 'users'" variety.js&lt;/pre&gt;
&lt;p&gt;The above is executed from terminal.&amp;#8221;test&amp;#8221; is the database containing the collection we are analyzing.&lt;/p&gt;
&lt;p&gt;Variety&amp;#8217;s output:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;{ "_id" : { "key" : "_id" }, "value" : { "types" : [ "object" ] }, "totalOccurrences" : 4, "percentContaining" : 100 }
{ "_id" : { "key" : "name" }, "value" : { "types" : [ "string" ] }, "totalOccurrences" : 4, "percentContaining" : 100 }
{ "_id" : { "key" : "bio" }, "value" : { "types" : [ "string" ] }, "totalOccurrences" : 3, "percentContaining" : 75 }
{ "_id" : { "key" : "pets" }, "value" : { "types" : [ "string", "array" ] }, "totalOccurrences" : 2, "percentContaining" : 50 }&lt;/pre&gt;
&lt;pre class="prettyprint"&gt;{ "_id" : { "key" : "someWeirdLegacyKey" }, "value" : { "type" : "string" }, "totalOccurrences" : 1, "percentContaining" : 25 }&lt;/pre&gt;
&lt;p&gt;Every document in the “users” collection has a &amp;#8220;name&amp;#8221; and &amp;#8220;_id&amp;#8221;. Most, but not all have a &amp;#8220;bio&amp;#8221;. Interestingly, it looks like &amp;#8220;pets&amp;#8221; can be either an array or a string. The application code really only expects arrays of pets. Have we discovered a bug, or a remnant of a previous schema?&lt;/p&gt;
&lt;p&gt;The first document created has a weird legacy key I&amp;#8217;ve never seen before- the people who built the prototype didn&amp;#8217;t clean up after themselves. These rare keys, whose contents are never used, have a strong potential to confuse developers, and could be removed once we verify our findings.&lt;/p&gt;
&lt;p&gt;For future use, results are also stored a varietyResults database.&lt;/p&gt;
&lt;h4&gt;Learn More!&lt;/h4&gt;
&lt;p&gt;Learn more about &lt;a href="https://github.com/JamesCropcho/variety"&gt;Variety&lt;/a&gt; now, including&lt;/p&gt;
&lt;p&gt;• How to download Variety&lt;/p&gt;
&lt;p&gt;• How to set a limit on the number of documents analyzed from a collection&lt;/p&gt;
&lt;p&gt;• How to contribute, and report issues&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/JamesCropcho/variety"&gt;Variety&lt;/a&gt; is free, open source, and written in 100% JavaScript. Check it out on &lt;a href="https://github.com/JamesCropcho/variety"&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;-by &lt;a href="https://twitter.com/#!/jamescropcho"&gt;James Cropcho&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.mongodb.org/post/21923016898</link><guid>http://blog.mongodb.org/post/21923016898</guid><pubDate>Fri, 27 Apr 2012 14:46:00 -0400</pubDate></item><item><title>MongoDB and Node.js at 10gen</title><description>&lt;p&gt;&lt;span id="internal-source-marker_0.23889884143136442"&gt;With their strong roots in JavaScript, Node.js and MongoDB have always been a natural fit, and the Node.js community has embraced MongoDB with a number of open source projects. To support the community&amp;#8217;s efforts, 10gen is happy to &lt;a href="https://www.10gen.com/press/nodejs-driver-for-mongodb-now-supported-by-10gen"&gt;announce&lt;/a&gt; that the &lt;a href="https://github.com/mongodb/node-mongodb-native"&gt;MongoDB Node.js driver&lt;/a&gt; will join the existing set of 12 officially supported drivers for MongoDB.&lt;br/&gt;&lt;br/&gt;The Node.js driver was born out of necessity. Christian Kvalheim started using Node.js in early 2010. He had heard good things about MongoDB but was disappointed to discover that no native driver had yet been developed. So, he got to work. Over the past two years, Christian has done amazing work in his driver, and it has matured through the contributions of a large community and the rigors of production. For some time now, the driver has been on par with 10gen&amp;#8217;s officially supported MongoDB drivers.  So we were naturally thrilled to welcome Christian full time at 10gen to continue his work on the Node.js driver. &lt;!-- more --&gt;&lt;br/&gt;&lt;br/&gt;If you&amp;#8217;ve used MongoDB with Node.js, you&amp;#8217;re probably familiar with Mongoose, a popular object-document mapper that&amp;#8217;s used atop the Node.js driver. We&amp;#8217;re really excited to announce that Aaron Heckmann, one of the authors of &lt;a href="http://mongoosejs.com/"&gt;Mongoose&lt;/a&gt;, has also joined the 10gen team.&lt;br/&gt;&lt;br/&gt;10gen is fully committed to making MongoDB a first class citizen in the Node.js ecosystem. We&amp;#8217;ve partnered with Node.js advocates Joyent and Microsoft. We&amp;#8217;ve seen fantastic companies built on Node.js and MongoDB like Learnboost, Ordr.in, and Trello. And with Aaron and Christian on board, we see a very promising future for developers wanting to use MongoDB with Node.js.&lt;br/&gt;&lt;br/&gt;Curious about the driver and how it works? Check out the documentation and watch some sessions on MongoDB’s integration with Node.js. &lt;br/&gt;&lt;br/&gt;&lt;a href="https://github.com/mongodb/node-mongodb-native"&gt;Github&lt;/a&gt;&lt;br/&gt;&lt;a href="http://www.mongodb.org/display/DOCS/node.JS"&gt;Node.js Language Center&lt;/a&gt;&lt;br/&gt;&lt;a href="http://www.10gen.com/presentations#programming_lang__javascript_nodejs"&gt;MongoDB and Node.js Presentations&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span id="internal-source-marker_0.23889884143136442"&gt;&lt;span&gt;Interested in working on MongoDB and Node.js? &lt;a href="http://www.10gen.com/contact"&gt;Drop us a line&lt;/a&gt;. We continue to look for other great engineers to join us in this effort.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;em&gt;link to the &lt;a href="https://www.10gen.com/press/nodejs-driver-for-mongodb-now-supported-by-10gen"&gt;press release&lt;/a&gt;&lt;/em&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;</description><link>http://blog.mongodb.org/post/21780849392</link><guid>http://blog.mongodb.org/post/21780849392</guid><pubDate>Wed, 25 Apr 2012 09:21:00 -0400</pubDate></item><item><title>Grails in the Land of MongoDB</title><description>&lt;p&gt;Groovy and Grails’ speed and simplicity are a perfect match to the flexibility and power of MongoDB. Dozens of plugins and libraries connect these two together, making it a breeze to get Grooving with MongoDB.&lt;/p&gt;
&lt;h4&gt;Using Grails with MongoDB&lt;/h4&gt;
&lt;p&gt;For the purpose of this post, let’s pretend we’re writing a hospital application that uses the following domain class.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;class Doctor { 
  String first 
  String last 
  String degree 
  String specialty 
}&lt;/pre&gt;
&lt;p&gt;There are a few grails plugins that help communicate with MongoDB, but one of the easiest to use is the one created by Graeme Rocher himself (Grails project lead). The MongoDB GORM plugin allows you to persist all your domain classes in MongoDB. To use it, first remove any unneeded persistance-related plugins after you’ve executed the ‘grails create-app’ command, and install the MongoDB GORM plugin.&lt;!-- more --&gt;&lt;/p&gt;
&lt;h4&gt;Using MongoDB GORM for Persistence&lt;/h4&gt;
&lt;p&gt;Step 1: Remove the hibernate dependency from the BuildConfig.groovy file. &lt;br/&gt;Step 2:Install the MongoDB GORM&lt;/p&gt;
&lt;pre class="prettyprint"&gt;plugin grails install-plugin mongodb&lt;/pre&gt;
&lt;p&gt;Step 3:Edit DataSource.groovy to specify connection settings. You can entirely remove the content of this configuration file and replace it with the following, or you can specify different connection settings for each of your environments (dev, test, prod):&lt;/p&gt;
&lt;pre class="prettyprint"&gt;grails { 
  mongo { 
    host = “localhost” 
    port = 27107 
    username = ”user” 
    password=”secretpassword” 
    databaseName = “physicians” 
  } 
}&lt;/pre&gt;
&lt;p&gt;And that’s it! You can continue building your Grails application as usual by generating your controllers, views, services, etc.&lt;/p&gt;
&lt;h4&gt;GORM and Mongo&lt;/h4&gt;
&lt;p&gt;Although GORM was specifically created to persist and manipulate objects in a ‘relational’ way, you can still use some of its powerful features with MongoDB. These include:&lt;/p&gt;
&lt;h5&gt;Basic GORM:&lt;/h5&gt;
&lt;pre class="prettyprint"&gt;Doctor.list() 
Doctor.get(5) 
Doctor.getAll(5,6,7) 
Doctor.list(max:5,sort:'first',order:'desc')
Doctor.listOrderBySpecialty() 
&lt;/pre&gt;
&lt;h5&gt;Dynamic Finders:&lt;/h5&gt;
&lt;pre class="prettyprint"&gt;Doctor.findByLast(“House”) 
Doctor.findAllBySpecialtyAndDegree(“Pediatrics”,”MD”)
&lt;/pre&gt;
&lt;h5&gt;Criteria Queries:&lt;/h5&gt;
&lt;pre class="prettyprint"&gt; Doctor.withCriteria{ eq("specialty", "Pediatrics") }
&lt;/pre&gt;
&lt;h5&gt;Projections:&lt;/h5&gt;
&lt;pre class="prettyprint"&gt;Doctor.withCriteria{ projections {countDistinct('specialty')} }&lt;/pre&gt;
&lt;h5&gt;Query by Example:&lt;/h5&gt;
&lt;pre class="prettyprint"&gt;def sampledoc = new Doctor(specialty:"Pediatrics") 
def docs = Doctor.findAll(sampledoc)
&lt;/pre&gt;
&lt;p&gt;Some of the GORM features that are not supported include:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Criteria queries on associations&lt;/li&gt;
&lt;li&gt;HQL&lt;/li&gt;
&lt;li&gt;Groovy SQL&lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt;The Schemaless Universe in a GORM World&lt;/h4&gt;
&lt;p&gt;This is where it gets exciting: with MongoDB, you can make domain objects do things that are impossible with a relational database. For example, you can now programmatically add properties on the fly based on your run time needs.&lt;/p&gt;
&lt;h4&gt;Dynamic Attributes&lt;/h4&gt;
&lt;p&gt;Let’s suppose that you want to add a ‘city’ property to your domain object. You can easily accomplish this without having to modify the original domain class using the subscript operator:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;def doc = new Doctor(first:”Julius”,last:”Hibbert”, degree:”MD”,specialty:”General Medicine”) 

// Add a city dynamically to this doctor 
doc["city"]="Springfield" 

// Saving it creates an instance of Doctor with the new field 
doc.save()&lt;/pre&gt;
&lt;p&gt;Dynamic Finders even work with dynamically added fields:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;def d = Doctor.findByCity(“Springfield”)&lt;/pre&gt;
&lt;h4&gt;Grails Identifiers and MongoDB Identifiers&lt;/h4&gt;
&lt;p&gt;A word of caution about ID generation. Grails automatically assigns an ID as an integer value. When a Doctor object is saved, the plugin creates an &lt;code&gt;_id&lt;/code&gt; within the document as follows:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;{ "_id" : NumberLong(1),...}&lt;/pre&gt;
&lt;p&gt;However, a normal insert in MongoDB, creates it as a BSON ObjectId:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;{ "_id" : ObjectId("4f2ca36b25f39d121957cebb"),...}&lt;/pre&gt;
&lt;p&gt;An extra collection is also created, &lt;code&gt;doctor.next_id&lt;/code&gt;, to keep track of the next id.&lt;/p&gt;
&lt;p&gt;To make ID generation compatible with MongoDB, you need to declare your ID explicitly as an ObjectID in your domain class:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;import org.bson.types.ObjectId
class Doctor {
     ObjectId id
     …
}&lt;/pre&gt;
&lt;h4&gt;Groovy and MongoDB&lt;/h4&gt;
&lt;p&gt;You can use Groovy and its scripting and metaprogramming powers with the help of Gmongo.&lt;/p&gt;
&lt;p&gt;Gmongo, written by Paulo Poiati, is a convenient wrapper around the MongoDB Java driver. Using Gmongo in your Groovy programs is the closest thing to writing commands directly into Mongo’s interactive shell.&lt;/p&gt;
&lt;p&gt;In version 0.9.3, Gmongo can be instantiated by calling it through Grapes:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;@Grab(group='com.gmongo', module='gmongo', version='0.9.3') 
import com.gmongo.GMongo 

// Instantiate gmongo.GMongo object 
// It defaults to localhost, but you can pass connection settings through the constructor 
def mongo = new GMongo() 

// Get a reference to the db
def db = mongo.getDB("physicianfinder")&lt;/pre&gt;
&lt;p&gt;Now you have a database object, which you can attach to your collection to run MongoDB commands. Here’s an example of the syntax:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;// [MongoDB database(usually just db)].[name of your collection].[command] 

// The following example returns the number of documents in a collection
Integer howmanydoctors = db.doctor.count()

// Finding documents with Gmongo
// Returns a com.mongodb.DBCursor class
def doctors = db.physician.find() 

// output each document to screen 
doctors.each { 
    println it 
} 

// Finds and returns one doctor
db.doctor.findOne()

// Find all doctors with last name 'Wu' 
db.doctor.find(last:"Wu") 

// Return last and specialty fields only
db.hospitals.find([:],[last:1,specialty:1]) 

// Using a regex, find all docs whose last name starts with 'H'
db.doctor.find([last: ~/^H/]) 

// Find and sort by specialty 
db.doctor.find().sort([specialty:1]) 

// Skip by 10, limit results by 5
db.doctor.find(specialty:”Pediatrics”).skip(10).limit(5) &lt;/pre&gt;
&lt;h4&gt;Saving data to MongoDB&lt;/h4&gt;
&lt;p&gt;Writing documents to MongoDB with Groovy is again very similar to how it’s done through the shell. You can also pass multiple types of collections to the &lt;code&gt;insert&lt;/code&gt; method and have it magically saved correctly as a document.&lt;/p&gt;
&lt;pre class="prettyprint"&gt; // Inserting a Doctor with two fields
db.doctor.insert([first:"Charles",last:"Darwin"]) 

// Specifying write concern
db.doctor.insert([first:"Gregory",last:"House"], com.mongodb.WriteConcern.NORMAL)

// Inserting nested documents: 
def hospital = [name:"My City Big Hospital", city:"Chicago", 
                buildings:[[address:"123 Main St.", name:"Feinberg",num_of_beds:300], 
                           [address:"345 Hope Ln.", name:"Galter",num_of_beds:100]]] 

// Saves the map of maps as a nested document
db.hospitals.insert(hospital)

// The following document is then created in the hospitals collection: 
{ "_id" : ObjectId("4f2c98d53b7e58ee6ea885d5"), 
  "name" : "My City Big Hospital", 
  "city" : "Chicago", 
   "buildings" : [ { "address" : "123 Main St.", "name" : "Feinberg", "num_of_beds" : 300 }, 
                   { "address" : "345 Hope Ln.", "name" : "Galter", "num_of_beds" : 100 } ] }&lt;/pre&gt;
&lt;p&gt;You can also use Groovy builders to generate your documents.&lt;/p&gt;
&lt;pre class="prettyprint"&gt; // Create a doctor with a JSON builder 
def builder = new groovy.json.JsonBuilder() 
builder.physicians { 
  doctor { first 'Julius' last 'Hibbert' 
          
           // Named arguments are valid values for objects too   
           address( city: 'Springield', 
                    country: 'USA', 
                    zip: 02105, ) 
           medicalschool: "Johns Hopkins University School of Medicine" 
           mensamember true 
           practice 'Dr. Julius Hibbert, M.D. Family Practice' } 
          } 

// Parse JSON string into a com.mongodb.util.JSON object 
def parsed = com.mongodb.util.JSON.parse(builder.toString()) 

// Save to Mongo 
db.physicians.insert(parsed)&lt;/pre&gt;
&lt;p&gt;Updating and removing are also straightforward:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;// Look for 'Darwin' and update first name to 'Charles'
db.doctor.update([last:"Darwin"],[$set:[first:"Charles"]]) 

// Delete all 'Darwins' 
db.doctor.remove(last:"Darwin")&lt;/pre&gt;
&lt;p&gt;If instead of collections you want to persist Plain Old Groovy Objects(POGOs), you can. Let’s start with our Doctor object from earlier:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;class Doctor { 
     def first 
     def last 
     def specialty }&lt;/pre&gt;
&lt;p&gt;You can insert an instance of it by doing the following:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;def doc = new Doctor(first:"Richard",last:"Kimble",specialty:"Pediatrics")&lt;/pre&gt;
&lt;p&gt;The doc instance also contains properties that we do not need to save into the document, so we remove the class and metaClass property before inserting:&lt;/p&gt;
&lt;pre class="prettyprint"&gt; // Get only the properties we want to save 
def doctor = doc.properties.findAll { !['class', 'metaClass'].contains(it.key) }

// Insert it into the doctor collection
db.doctor.insert(doctor)&lt;/pre&gt;
&lt;p&gt;And we can retrieve it back as a POGO as well:&lt;/p&gt;
&lt;pre class="prettyprint"&gt; // Ignore the _id property 
Doctor docFromMongo = db.doctor.findOne(last:"Kimble").findAll { it.key != '_id' }
&lt;/pre&gt;
&lt;p&gt;And if you don’t have a POGO declared, you can use the magic of the Expando class to retrieve any document into a Groovy class:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;Expando docFromMongo = db.doctor.findOne(last:"Kimble")&lt;/pre&gt;
&lt;p&gt;We’ve only covered the basics of interacting with MongoDB, but there are many more features you can leverage for making the most of the NoSQL world. To get started, check out the &lt;a href="http://grails.org/plugin/mongodb"&gt;MongoDB GORM plugin&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;— Ariel Gamino&lt;/p&gt;</description><link>http://blog.mongodb.org/post/18510469058</link><guid>http://blog.mongodb.org/post/18510469058</guid><pubDate>Wed, 29 Feb 2012 16:31:00 -0500</pubDate><category>grails</category><category>mongodb</category><category>groovy</category><category>groovy on grails</category></item><item><title>Operations in the New Aggregation Framework</title><description>&lt;p&gt;Available in &lt;a href="http://www.mongodb.org/downloads"&gt;2.1 development release&lt;/a&gt;. Will be stable for production in the &lt;a href="http://www.mongodb.org/display/DOCS/2.2+Release+Notes"&gt;2.2 release&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Built by Chris Westin (&lt;a href="https://twitter.com/#!/cwestin63"&gt;@cwestin63&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;MongoDB has built-in &lt;a href="http://www.mongodb.org/display/DOCS/MapReduce"&gt;MapReduce&lt;/a&gt; functionality that can be used for complex analytics tasks. However, we’ve found that most of the time, users need the kind of group-by functionality that SQL implementations have. This can be implemented using map/reduce, but doing so is more work than it was in SQL. In version 2.1, MongoDB is introducing a new &lt;a href="http://www.mongodb.org/display/DOCS/Aggregation+Framework"&gt; aggregation framework&lt;/a&gt; that will make it much easier to obtain the kind of results SQL group-by is used for, without having to write custom JavaScript.&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;MongoDB provides an easy way to store documents that aren’t just flat records like SQL, but that also contain arrays and nested documents. Another common problem users have told us about is that it can be difficult to manipulate these sub-parts of documents easily. The new aggregation mechanism is also taking on making this easier, by providing operators that can be used to disassemble and re-assemble document sub-parts.&lt;/p&gt;
&lt;p&gt;After many requests, we have also included expression evaluation to return computed values—for &lt;em&gt;virtual fields&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The new aggregation framework is declarative. Rather than writing code to aggregate data, you specify a chain of operations, called a “pipeline,” to apply to your documents. This is similar to a pipe in a unix shell.&lt;/p&gt;
&lt;p&gt;We’re now going to show you a few short examples (using the mongo shell) of this new functionality to get you started.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;$match&lt;/strong&gt; is a pipeline operator that filters out documents that don’t match the specified condition. For example&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;code&gt;db.runCommand({ aggregate : "article", pipeline : [ { $match : { author : "dave" } } ]}); &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This very simple one step pipeline doesn’t introduce any new functionality yet, but shows how to put a query at the beginning of your pipeline. For those of you familiar with MongoDB, this is the equivalient of&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;code&gt;&amp;gt; db.article.find({ author : "dave" }); &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;$project&lt;/strong&gt; is a pipeline operator that let’s you select which fields you want to include or exclude from a result. You can also create new virtual fields from computed values. Here is a simple example, building on the previous one:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;code&gt;db.runCommand({ aggregate : "article", pipeline : [ { $match : { author : "dave" } }, { $project : { _id : 0, author : 1, tags : 1 }} ]}); &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As before, this doesn’t introduce anything radically new; this is the equivalent of&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;code&gt;&amp;gt; db.article.find({ author : "dave" }, { _id : 0, author : 1, tags : 1); &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While this functionality was available before from &lt;code&gt;find()&lt;/code&gt;, what it does demonstrate here is how to put together more than one aggregation pipeline operator. The value of &lt;code&gt;pipeline&lt;/code&gt; is an array consisting of the operators to apply. Conceptually, the aggregation framework behaves as if it was feeding the result of scanning the target collection through that pipeline.&lt;/p&gt;
&lt;p&gt;Now let’s take a look at some new functionality that wasn’t available before.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;$unwind&lt;/strong&gt; hands out the elements of an array one at a time; each element is surrounded by the document that contains the original array. For this example, we’ll first show what a document from the &lt;code&gt;article&lt;/code&gt; collection looks like. Suppose we had saved this:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;code&gt;db.article.save( { title : "this is your title" , author : "dave" , posted : new Date(4121381470000) , pageViews : 7 , tags : [ "fun" , "nasty" ] , comments : [ { author :"barbara" , text : "this is interesting" } , { author :"jenny" , text : "i like to play pinball", votes: 10 } ], other : { bar : 14 } }); &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, we can unwind the &lt;code&gt;tags&lt;/code&gt; array as follows:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;code&gt;db.runCommand({ aggregate : "article", pipeline : [ { $unwind : "$tags" } ]}); &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result looks like this:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;code&gt;{ "result" : [ { "_id" : ObjectId("4eeeb5fef09a7c9170df094b"), "title" : "this is your title", "author" : "dave", "posted" : ISODate("2100-08-08T04:11:10Z"), "pageViews" : 7, "tags" : "fun", "comments" : [ { "author" : "barbara", "text" : "this is interesting" }, { "author" : "jenny", "text" : "i like to play pinball", "votes" : 10 } ], "other" : { "bar" : 14 } }, { "_id" : ObjectId("4eeeb5fef09a7c9170df094b"), "title" : "this is your title", "author" : "dave", "posted" : ISODate("2100-08-08T04:11:10Z"), "pageViews" : 7, "tags" : "nasty", "comments" : [ { "author" : "barbara", "text" : "this is interesting" }, { "author" : "jenny", "text" : "i like to play pinball", "votes" : 10 } ], "other" : { "bar" : 14 } } ], "ok" : 1 } &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that the single document has been duplicated (see the identical _id values). However, the &lt;code&gt;tags&lt;/code&gt; array in each copy of the document has been replaced with one value from the original &lt;code&gt;tags&lt;/code&gt;array.&lt;/p&gt;
&lt;p&gt;$unwind isn’t useful on its own, but is useful when combined with $match, which can be used to filter out copies of the document without values of interest, and then the array can be reassembled using other operators such as $push or $addToSet. $unwind is also useful when combined with $group.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;$group&lt;/strong&gt; groups elements with a common key together, and allows the application of aggregation functions. For the purposes of a small example, let’s add a second article to our collection:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;code&gt;db.article.save( { title : "this is some other title" , author : "jane" , posted : new Date(978239834000) , pageViews : 6 , tags : [ "nasty" , "filthy" ] , comments : [ { author :"will" , text : "i don't like the color" } , { author :"jenny" , text : "can i get that in green?" } ], other : { bar : 14 } }); &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If these articles represent content on a web site, I might want to know what tags users are applying to these articles. I can use $group to find that out like so:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;code&gt;db.runCommand({ aggregate : "article", pipeline : [ { $unwind : "$tags" }, { $group : { _id : "$tags", count : { $sum : 1 }, authors : { $addToSet : "$author" } }} ]}); &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The grouping key for a $group is defined by specifying a field (or subdocument of multiple fields) for the _id. The grouping key is used to define buckets into which documents are put. Other fields are aggregate functions that can compute values across the entries in each bucket.&lt;/p&gt;
&lt;p&gt;In this case, one is added to &lt;code&gt;count&lt;/code&gt; for each document that matches the group key. That counts up the number of items in each bucket. &lt;code&gt;authors&lt;/code&gt; will be an array, and each unique author in the bucket will be added to it.&lt;/p&gt;
&lt;p&gt;The result of all this is&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&lt;code&gt;{ "result" : [ { "_id" : "filthy", "count" : 1, "authors" : [ "jane" ] }, { "_id" : "fun", "count" : 1, "authors" : [ "dave" ] }, { "_id" : "nasty", "count" : 2, "authors" : [ "jane", "dave" ] } ], "ok" : 1 } &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One document has the “filthy” tag, and it was written by jane. One document has the “fun” tag, and it was written by dave. Two documents have the “nasty” tag, and both jane and dave wrote documents with that tag.&lt;/p&gt;
&lt;p&gt;The new aggregation functionality is available only by compiling from source. It is available in the &lt;a href="http://www.mongodb.org/downloads"&gt;2.1 development release&lt;/a&gt; but is not meant for production. &lt;a href="http://www.mongodb.org/display/DOCS/2.2+Release+Notes"&gt;MongoDB 2.2&lt;/a&gt; will be the first stable release with the aggregation framework. For more examples and information, check out the &lt;a href="http://www.10gen.com/presentations/mongosv-2011/mongodbs-new-aggregation-framework"&gt;talk and demo from MongoSV 2011&lt;/a&gt;, or the &lt;a href="http://www.mongodb.org/display/DOCS/Aggregation+Framework"&gt; documentation on the MongoDB wiki&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;by Chris Westin&lt;/strong&gt;&lt;/p&gt;</description><link>http://blog.mongodb.org/post/16015854270</link><guid>http://blog.mongodb.org/post/16015854270</guid><pubDate>Tue, 17 Jan 2012 14:04:00 -0500</pubDate></item><item><title>MongoSV Recap</title><description>&lt;p&gt;Last week over 1,100 developers came together for MongoSV, the largest MongoDB conference to date. 10gen kicked off MongoSV with our inaugural &lt;a href="http://blog.10gen.com/post/13885501875/announcing-the-mongodb-masters"&gt;MongoDB Masters program&lt;/a&gt;, which brought together MongoDB evangelists from around the world.&lt;/p&gt;
&lt;p&gt;At the opening keynote, 10gen CTO Eliot Horowitz demoed a &lt;a href="https://github.com/erh/mongosv-twitter-demo"&gt;twitter app&lt;/a&gt; for #mongoSV tweets, featuring the new aggregation framework expected for the MongoDB 2.2 release. These gather all the tweets sent out with the hashtag #mongoSV and organizes them in by recency and most retweets. Get the source code for the demo app &lt;a href="https://github.com/erh/mongosv-twitter-demo"&gt;here&lt;!-- more --&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Highlights from MongoSV include presentations on &lt;a href="http://www.10gen.com/presentations/mongosv-2011/x.commerce-makes-a-big-bet-on-open-source"&gt;X.commerce&amp;#8217;s new open source developer platform&lt;/a&gt;, &lt;a href="http://www.10gen.com/presentations/mongosv-2011/hands-on-deploying-mongodb-on-azure"&gt;MongoDB&amp;#8217;s integration with Azure&lt;/a&gt;, &lt;a href="http://www.10gen.com/presentations/mongosv-2011/mongodbs-new-aggregation-framework"&gt;MongoDB&amp;#8217;s new aggregation framework&lt;/a&gt;, &lt;a href="http://www.10gen.com/presentations/mongosv-2011/a-year-with-mongodb-running-operations-to-keep-the-game-magic-alive"&gt;How Disney manages their deployment of 1400 Mongo instances&lt;/a&gt; and &lt;a href="http://www.10gen.com/presentations#event__mongosv-2011"&gt;more&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;br/&gt;&lt;img src="http://media.tumblr.com/tumblr_lwb69nTtFV1qzyevi.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;img src="http://media.tumblr.com/tumblr_lwb64l1wki1qzyevi.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;img src="http://media.tumblr.com/tumblr_lw658bdaNQ1qzyevi.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;img src="http://media.tumblr.com/tumblr_lw658h2E3C1qzyevi.jpg"/&gt;&lt;br/&gt;&lt;br/&gt; the 10gen booth at MongoSV &lt;br/&gt;&lt;br/&gt;&lt;img src="http://media.tumblr.com/tumblr_lw658588fy1qzyevi.jpg"/&gt;&lt;br/&gt;&lt;br/&gt; 10gen President Max Schireson welcomes the Speakers and Masters to MongoSV &lt;/p&gt;</description><link>http://blog.mongodb.org/post/14318434522</link><guid>http://blog.mongodb.org/post/14318434522</guid><pubDate>Fri, 16 Dec 2011 14:57:00 -0500</pubDate><category>mongoSV</category><category>MongoDB</category><category>conference</category><category>databases</category><category>database</category><category>noSQL</category></item><item><title>MongoDB On Microsoft Azure</title><description>&lt;p&gt;A new preview release of the MongoDB controller for Azure is available. This release includes support for replica sets, and over the coming months, we’ll be adding support for MongoDB’s sharding facilities. We’ll also be working to more tightly integrate MongoDB with the features of Azure platform. Each member of a replica set is hosted by an instance of an Azure worker role, so the size of the replica set is determined by the number of instances configured for the the replica set worker roles. Each replica set worker role creates a child process to run the mongod server process. The controller defines an Azure worker role which represents a MongoDB cluster. &lt;!-- more --&gt;Currently the cluster consists of a single MongoDB replica set. Each role instance participates as a member of the replica set. On deployment the controller configures the replica set and initiates it. Role instances handle restarts, including assuming identity for a replica set member and replacing old instances. The worker role also integrates with Azure Diagnostics to capture trace and performance counter information. The MongoDB Azure wrapper release is currently delivered as a Visual Studio 2010 solution with associated source files, and we’ll follow that up in the future with packaging and deployment tools. To get started, take a look at the &lt;a href="http://www.mongodb.org/display/DOCS/MongoDB+on+Azure"&gt;documentation&lt;/a&gt; or browse through the &lt;a href="https://github.com/mongodb/mongo-azure"&gt;source&lt;/a&gt;. We’ve included a small sample application to get you up and running quickly. If you have questions, head over to our &lt;a href="https://groups.google.com/group/mongodb-user/"&gt;user mailing list&lt;/a&gt; or file a bug report on our &lt;a href="https://jira.mongodb.org/browse/AZURE"&gt;JIRA&lt;/a&gt; system. Microsoft will be presenting at the &lt;a href="http://www.10gen.com/events/mongosv-2011"&gt;MongoSV&lt;/a&gt; conference in Santa Clara on December 9th. It will be a great opportunity to understand the solution in depth, as well as understand the future direction of this project. We hope to see you there.&lt;/p&gt;</description><link>http://blog.mongodb.org/post/13594969869</link><guid>http://blog.mongodb.org/post/13594969869</guid><pubDate>Thu, 01 Dec 2011 12:54:00 -0500</pubDate></item><item><title>MongoDB Monitoring Service Docs Available</title><description>&lt;p&gt;&lt;a href="https://mms.10gen.com/user/register?c=blog"&gt;MongoDB Monitoring Service&lt;/a&gt; (MMS) documentation now available: &lt;a href="http://mms.10gen.com/help/"&gt;&lt;a href="http://mms.10gen.com/help/"&gt;http://mms.10gen.com/help/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.mongodb.org/post/12290838151</link><guid>http://blog.mongodb.org/post/12290838151</guid><pubDate>Thu, 03 Nov 2011 14:53:48 -0400</pubDate></item><item><title>Mongo Boston Recap</title><description>&lt;p&gt;Last week 250 developers converged at the Microsoft New England Research and Design Center for &lt;a href="http://www.10gen.com/events/mongo-boston-2011"&gt;Mongo Boston&lt;/a&gt;. Highlights from the event include presentations on &lt;a href="http://www.10gen.com/presentation/mongoboston-2011/welcome-and-whats-new-in-mongodb-2.0"&gt;MongoDB 2.0&lt;/a&gt;, &lt;a href="http://www.10gen.com/presentation/mongoboston-2011/how-mtv-leverages-mongodb-for-cms"&gt;how MTV leverages MongoDB for CMS&lt;/a&gt;,  &lt;a href="http://www.10gen.com/presentation/mongoboston-2011/cowboy-coding-learn-when-and-how-to-break-all-the-rules-for-really-rapid-prototyping"&gt;rapid prototyping&lt;/a&gt;, and &lt;a href="http://www.10gen.com/presentations#event__mongoboston-2011"&gt;more&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/49439061@N04/6221048217/" title="074_DP_5132 by mongodb, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6172/6221048217_500d2fc963.jpg" width="500" height="333" alt="074_DP_5132"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;More photos from the event are available on the &lt;a href="http://www.flickr.com/photos/49439061@N04/sets/72157627716787783/with/6221048217/"&gt;MongoDB Flickr&lt;/a&gt; page.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;If you missed the event, join the &lt;a href="http://www.meetup.com/Boston-MongoDB-User-Group/events/35018592/"&gt;Boston MongoDB User Group&lt;/a&gt;, which also meets at NERD. The next meeting is on November 15.&lt;/p&gt;</description><link>http://blog.mongodb.org/post/11321480271</link><guid>http://blog.mongodb.org/post/11321480271</guid><pubDate>Tue, 11 Oct 2011 13:42:56 -0400</pubDate></item><item><title>2.0 Presentation at New York MongoDB User Group</title><description>&lt;p&gt;On Thursday MongoDB core committer Eliot Horowitz presented to the &lt;a href="http://www.meetup.com/New-York-MongoDB-User-Group/"&gt;New York MongoDB User Group&lt;/a&gt; on the latest features in v2.0. The event was hosted by &lt;a href="https://www.sailthru.com/"&gt;Sailthru&lt;/a&gt;, a MongoDB-powered startup doing intelligent email marketing. The meetup was announced Monday night and within a day was oversubscribed. After the presentation, we all went out for drinks to celebrate the release. &lt;br/&gt;&lt;br/&gt; The NY MUG has over 1,000 members and meets monthly. There are also MongoDB user groups in &lt;a href="http://www.meetup.com/San-Francisco-MongoDB-User-Group/"&gt;San Francisco&lt;/a&gt;, &lt;a href="http://www.meetup.com/Washington-DC-MongoDB-Users-Group/"&gt;Washington DC&lt;/a&gt;, &lt;a href="http://www.meetup.com/London-MongoDB-User-Group/"&gt;London&lt;/a&gt;, &lt;a href="http://www.meetup.com/Boston-MongoDB-User-Group"&gt;Boston&lt;/a&gt;, &lt;a href="http://groups.google.com/group/mongodb-jp"&gt;Japan&lt;/a&gt;, and &lt;a href="http://www.mongodb.org/display/DOCS/MongoDB+User+Groups+%28MUGs%29"&gt;more&lt;/a&gt;. And if there isn&amp;#8217;t a MongoDB meetup in your city, we&amp;#8217;re happy to support you if you would like to &lt;a href="http://www.10gen.com/user-groups#Start"&gt;start one&lt;/a&gt;. &lt;!-- more --&gt;&lt;br/&gt;&lt;br/&gt; In case you missed the meetup, video and photos are posted below. Enjoy! &lt;br/&gt;&lt;br/&gt;&lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,47,0" height="270" id="flashObj" width="480"&gt;&lt;param name="movie" value="http://c.brightcove.com/services/viewer/federated_f9?isVid=1&amp;amp;isUI=1"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="flashVars" value="@videoPlayer=1170761477001&amp;amp;playerID=596005226001&amp;amp;playerKey=AQ~~,AAAAipOTmrk~,ppF_qxBkWm4G-M_tDdbW6qnuU4iUxLyo&amp;amp;domain=embed&amp;amp;dynamicStreaming=true"&gt;&lt;param name="base" value="http://admin.brightcove.com"&gt;&lt;param name="seamlesstabbing" value="false"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="swLiveConnect" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/object&gt; &lt;br/&gt;&lt;br/&gt;&lt;img alt="Q9159035" height="500" src="http://farm7.static.flickr.com/6067/6154093700_6b58849a3b.jpg" width="469"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;img alt="Q9159065" height="282" src="http://farm7.static.flickr.com/6165/6154098556_30927f936a.jpg" width="500"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;img alt="Q9159058" height="321" src="http://farm7.static.flickr.com/6191/6154097014_08f56cdf69.jpg" width="500"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;img alt="Q9159190" height="402" src="http://farm7.static.flickr.com/6203/6153567847_3c262d12f6.jpg" width="500"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;img alt="Q9159136" height="391" src="http://farm7.static.flickr.com/6160/6153564149_25c531c21b.jpg" width="500"/&gt;&lt;/p&gt;</description><link>http://blog.mongodb.org/post/10450332040</link><guid>http://blog.mongodb.org/post/10450332040</guid><pubDate>Tue, 20 Sep 2011 15:46:00 -0400</pubDate></item><item><title>Cache Reheating - Not to be Ignored</title><description>&lt;p&gt;An important aspect to keep in mind with databases is the cost of cache reheating after a server restart. Consider the following diagram which shows several cache servers (e.g., memcached) in front of a database server.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_lrkzxcKo0g1qzyevi.png"/&gt;&lt;/p&gt;
&lt;p&gt;This sort of setup is common and can work quite well when appropriate; it removes read load from the database and allows more RAM to be utilized for scaling (when the database doesn&amp;#8217;t scale horizontally). But what happens if all the cache servers restart at the same time, say, on a power glitch in a data center?&lt;!-- more --&gt;&lt;/p&gt;
&lt;p&gt;We then have a cache reheating scenario. After the bounce the full load of all read requests will hit the database server (for a while) given the caches are empty. The server won&amp;#8217;t be able to handle it (that&amp;#8217;s why the cache servers were there in the first place). Now if the reheat time is short, this is not a big problem&amp;#160;: we did go down after all. But if reheat takes a long time, it&amp;#8217;s a big problem. Imagine 20 cache servers with 64GB RAM each. 1.2 terabytes of data must be queried from the database to be fully reheated!&lt;/p&gt;
&lt;p&gt;Even without a cache server, the same issue exists for almost all databases. Imagine a server restart on a system with 64GB RAM. If loading 100MB/sec, reheat will take 10 minutes. However, if the queries are coming in randomly, it could take much much longer &amp;#8212; only with sequential I/O can we get anywhere near that speed.&lt;/p&gt;
&lt;p&gt;One could just sequentially read data in and fill the cache. However for databases much larger than RAM, loading in the right portion is difficult. &amp;#8220;Hot&amp;#8221; data could be at very different locations in the terabyte(s) of on disk data.&lt;/p&gt;
&lt;p&gt;A very nice attribute of the MongoDB storage engine is its use of memory-mapped files. In this model the cache is the operating system&amp;#8217;s file system cache. Restart the mongod process, and there is no reheat issue at all. Some databases use their own page cache which causes a reheat scenario even on just a process restart. Of course on a full server reboot MongoDB must reheat too.&lt;/p&gt;
&lt;p&gt;A few points to keep in mind:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Think about reheating and how you will operationally handle it if a scenario involving it occurs. For schedules OS maintenance restart the server during off peak hours to minimize the load during reheat.&lt;/li&gt;
&lt;li&gt;Restarting the mongod process is safe with respect to reheating.&lt;/li&gt;
&lt;li&gt;Remounting a volume likely loses all file system cache info for the volume.&lt;/li&gt;
&lt;li&gt;On a server restart, copy datafiles to /dev/null to force reheating to be sequential and thus much faster. This can be done even if the mongod process is already running. If the database is larger than RAM, copy only the newest datafiles (ones with the highest numbers); while this isn&amp;#8217;t perfect, the latest files likely contain the largest percentage of frequently used data.&lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.mongodb.org/post/10407828262</link><guid>http://blog.mongodb.org/post/10407828262</guid><pubDate>Mon, 19 Sep 2011 13:56:00 -0400</pubDate></item><item><title>MongoDB 2.0 Released</title><description>&lt;p&gt;&lt;span&gt;The MongoDB development team is pleased to announce the release of version 2.0.0.  Version 2.0 is the latest stable release, following the March 2011 release of version 1.8.  This release includes many new features, improvements to existing features, and performance enhancements.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Please note version 2.0 is a significant new release, but is 2.0 solely because 1.8 + 0.2 = 2.0; for example the upgrade from 1.6 to 1.8 was similar in scope.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Highlights of the 2.0 release:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.google.com/url?q=http%3A%2F%2Fwww.mongodb.org%2Fdisplay%2FDOCS%2F2.0%2BRelease%2BNotes%232.0ReleaseNotes-ConcurrencyImprovements&amp;amp;sa=D&amp;amp;sntz=1&amp;amp;usg=AFQjCNFPuopL1dnlbfMt-m9gRDHwo6Nvag"&gt;Concurrency improvements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/2.0+Release+Notes#2.0ReleaseNotes-IndexPerformanceEnhancements"&gt;Index enhancements to improve size and performance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/Security+and+Authentication#SecurityandAuthentication-ReplicaSetandShardingAuthentication"&gt;Authentication with sharded clusters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/2.0+Release+Notes#2.0ReleaseNotes-Datacenterawareness"&gt;Replica Set Data Center Awareness&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/Journaling"&gt;Journaling&lt;/a&gt;&lt;span&gt; is now enabled by default.  Journal files are now compressed.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/getLastError+Command"&gt;User defined getLastError options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/2.0+Release+Notes#2.0ReleaseNotes-DefaultStackSize"&gt;Smaller default stack size to accommodate more connections&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/compact+Command"&gt;Compact Command&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/2.0+Release+Notes#2.0ReleaseNotes-GeospatialFeatures"&gt;Geo-spatial features&lt;/a&gt;
&lt;ul&gt;&lt;li&gt;&lt;span&gt;Multi-location documents&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;Polygon searches&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/2.0+Release+Notes#2.0ReleaseNotes-Outputtoashardedcollection"&gt;Output map/reduce results to sharded collection&lt;!-- more --&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;span&gt;Concurrency improvements in 2.0 are just the start of a much larger concurrency roadmap we are working on.  In 2.0, we are beginning to address one of the biggest issues: holding locks during a page fault.  2.0 tracks memory caching and has the ability to yield locks and fault outside.  This is hooked in a number places, notably: updates by _id, remove, and long table scans.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Being able to keep the working index set in memory is an important factor in overall performance, and we overhauled indexes to make this easier.  Indexes in 2.0 are about 25% smaller and faster, meaning that you can fit more in memory.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Replica sets get two new important features in 2.0: priorities and tagging.  Priorities let you have nodes that you prefer to be primary if you have a non homogeneous environment.  Tagging lets you guarantee writes hit certain groups of servers.  One use case for this is guaranteeing a new user registration is written to two data centers before acknowledging to a user.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;There were many other improvements, so we encourage those interested to look at the change log.  Overall, this release added a large number of small performance and concurrency improvements, greater stability to sharding, and better replica set operations.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;span &amp;gt;Downloads: &amp;lt;span &amp;gt;&lt;a href="http://www.mongodb.org/downloads"&gt;&lt;a href="http://www.mongodb.org/downloads"&gt;http://www.mongodb.org/downloads&lt;/a&gt;&lt;/a&gt;&amp;lt;span &amp;gt; &lt;/p&gt;
&lt;p&gt;&amp;lt;span &amp;gt;Release Notes: &amp;lt;span &amp;gt;&lt;a href="http://www.mongodb.org/display/DOCS/2.0+Release+Notes"&gt;&lt;a href="http://www.mongodb.org/display/DOCS/2.0+Release+Notes"&gt;http://www.mongodb.org/display/DOCS/2.0+Release+Notes&lt;/a&gt;&lt;/a&gt;&amp;lt;span &amp;gt; &lt;/p&gt;
&lt;p&gt;&amp;lt;span &amp;gt;Full change log: &lt;a href="https://jira.mongodb.org/secure/IssueNavigator.jspa?requestId=10140"&gt;https://jira.mongodb.org/secure/IssueNavigator.jspa?requestId=10140&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;For the full scoop on what’s new in MongoDB version 2.0, register for our live webinar on Thursday, September 15th. We will have two sessions: the first at &lt;a href="http://www.10gen.com/events/mongodb-version-2dot0-s1"&gt;10am GMT&lt;/a&gt;, and another at &lt;a href="http://www.10gen.com/events/mongodb-version-2dot0-s2"&gt;1:30pm ET/10:30am PT&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Thank you to the MongoDB community for your continued feedback and testing through the 1.9 development series.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;-Eliot and the MongoDB Team&lt;/span&gt;&lt;/p&gt;</description><link>http://blog.mongodb.org/post/10126837729</link><guid>http://blog.mongodb.org/post/10126837729</guid><pubDate>Mon, 12 Sep 2011 11:32:00 -0400</pubDate></item><item><title>BSON and Data Interchange</title><description>&lt;p&gt;There’s a lot of good things about JSON &amp;#8212; it’s a standards based, language independent, representation of object-like data. Also, it’s easy to read (for users and programmers alike). Each document is only about data, not complex object graphs and links. Thus it’s easy to inspect without knowing all the code of an application. &lt;br/&gt;&lt;br/&gt; Further, JSON is “schemaless”. We do not have to predefine our (protocol) schema. This can be quite helpful: imagine RPC’ing data from client A to server B with a fixed schema for the messages. On a schema change both need to be ‘updated’ with the new schema. If there are many components to the system it’s even more complicated of course. There is some analogy here to XML, which can (optionally) be schemaless. &lt;br/&gt;&lt;br/&gt; It would be nice to have a binary representation of JSON. That is what &lt;a href="http://bsonspec.org/"&gt;BSON&lt;/a&gt; is all about. &lt;br/&gt;&lt;!-- more --&gt;&lt;br/&gt;So what are the goals of BSON? They are:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Fast scan-ability.&lt;/strong&gt; For very large JSON documents, scanning can be slow. To skip a nested document or array we have to scan through the intervening field completely. In addition as we go we must count nestings of braces, brackets, and quotation marks. In BSON, the size of these elements is at the beginning of the field’s value, which makes skipping an element easy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easy manipulation.&lt;/strong&gt; We want to be able to modify information within a document efficiently. For example, incrementing a field’s value from 9 to 10 in a JSON text document might require shifting all the bytes for the remainder of the document, which if the document is large could be quite costly. (Albeit this benefit is not comprehensive: adding an element to an array mid-document would result in shifting.) It’s also helpful to not need to translate the string “9” to a numeric type, increment, and then translate back.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Additional data types.&lt;/strong&gt; JSON is potentially a great interchange format, but it would be nice to have a a few more data types. Most importantly is the addition of a “byte array” data type. This avoids any need to do base64 encoding, which is awkward.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;br/&gt; One thing that is not a goal of BSON: compactness. The JSON document {“field”:7} represents the number seven as a single byte. That’s pretty good. &lt;br/&gt;&lt;br/&gt; Perhaps the best example to date of usage of BSON is MongoDB. MongoDB uses it heavily &amp;#8212; for sending documents over the network, persisting them to disk, as well as for internal data manipulations. In fact this is where BSON originated, although today it is a separate spec that should not be considered coupled to any one particular project. &lt;br/&gt;&lt;br/&gt; There is BSON serialization and deserialization code for most languages; implementations are open source and mostly available under Apache 2 license. Quite a few implementations originated from a MongoDB drivers; work is underway in most drivers to fully decouple, although independent use works fine today. &lt;br/&gt;&lt;br/&gt; If you or someone you know is using BSON in a project, please let us know by posting on the &lt;a href="http://groups.google.com/group/bson"&gt;BSON mailing list&lt;/a&gt;. Check out &lt;a href="http://bsonspec.org/"&gt;bsonspec.org&lt;/a&gt; for more information. &lt;br/&gt;&lt;br/&gt; &amp;#8212; &lt;a href="http://twitter.com/#!/stbrody"&gt;Spencer&lt;/a&gt; &amp;amp; &lt;a href="http://twitter.com/#!/dmerr"&gt;Dwight&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.mongodb.org/post/9333386434</link><guid>http://blog.mongodb.org/post/9333386434</guid><pubDate>Wed, 24 Aug 2011 09:52:00 -0400</pubDate></item><item><title>Master Detail Transactions in MongoDB</title><description>&lt;p&gt;In relational databases, transactions let you make reliable atomic updates to your data. Because relational schemas are often highly normalized, most logical transactions span multiple tables, so it is important to be able to do multiple updates atomically (all or nothing).&lt;/p&gt;
&lt;p&gt;While MongoDB does not have multi-document transactions, it makes up for this in many use cases through its document oriented data model. In this post, we’ll talk about the Master-Detail design pattern that comes up very often in data modelling that almost always requires multi-statement transactions in an RDBMS, but is easily handled without cross-statement transactions in MongoDB.&lt;!-- more --&gt;&lt;/p&gt;
&lt;h3&gt;Master-Detail transactions in an RDBMS&lt;/h3&gt;
&lt;p&gt;As an example of the Master-Detail pattern, consider a Purchase Order with multiple line items. In an RDBMS, we might model this as a Purchase Order table (the Master) and a Line Item table (the Detail). To get a purchase order, I need to join Purchase Order and Line Item tables together to get all of the info in the purchase order.&lt;/p&gt;
&lt;p&gt;I might model my Purchase Orders as follows in an RDBMS:&lt;/p&gt;
&lt;script src="https://gist.github.com/1068265.js?file=po_schema.sql" type="text/javascript"&gt;&lt;/script&gt;&lt;p&gt;If I want to make atomic updates to a purchase order and its line items, I need a multi-statement transaction. For example, if I am going to create a purchase order, I might follow these steps:&lt;/p&gt;
&lt;script src="https://gist.github.com/1068265.js?file=insert_po.sql" type="text/javascript"&gt;&lt;/script&gt;&lt;p&gt;With this update, there is never a time where the Purchase Order exists but has no Line Items in it. The whole object and its details are committed in a single transaction.&lt;/p&gt;
&lt;p&gt;Now if I need to update that Purchase Order, say to add a few more line items, then I would perform another transaction.&lt;/p&gt;
&lt;script src="https://gist.github.com/1068265.js?file=update_po.sql" type="text/javascript"&gt;&lt;/script&gt;&lt;p&gt;This time I’ve ensured that my two new Line Items appear at the same time (or not at all) and that the total field of the Purchase Order is updated at the same time. No client will ever see a state in which only one of those Line Items exists nor any state where the total does not match the sum of the line items.&lt;/p&gt;
&lt;h3&gt;Master-Detail in MongoDB&lt;/h3&gt;
&lt;p&gt;Working with MongoDB is a bit different. While we don’t have the ability to perform multi-documents transactions (at least so far). However this Master-Detail pattern can be handled without multi-statement transactions thanks to MongoDB’s richer data model.&lt;/p&gt;
&lt;p&gt;MongoDB can store data as documents with nested objects, arrays, and other rich data types. Thus we don’t need to store Master-Detail entities in multiple collections, or even in more than one document. A common way of modeling such objects with MongoDB is using nested documents. So our Purchase Order model might look like this:&lt;/p&gt;
&lt;script src="https://gist.github.com/1068265.js?file=po_document.js" type="text/javascript"&gt;&lt;/script&gt;&lt;p&gt;Let’s look at how we can get the same level of atomicity from MongoDB without needing multi-statement transactions!&lt;/p&gt;
&lt;p&gt;First, we want to be able to create a new purchase order and its first line items atomically.&lt;/p&gt;
&lt;script src="https://gist.github.com/1068265.js?file=po_insert.js" type="text/javascript"&gt;&lt;/script&gt;&lt;p&gt;This atomically creates the purchase order and its initial items in a single operation. Just as with the SQL scenario, clients will never see a point in time where the purchase order is empty. It all succeeds in a single step.&lt;/p&gt;
&lt;p&gt;Now what about modifying that purchase order? If we want to add some items to the PO, we can do so like this:&lt;/p&gt;
&lt;script src="https://gist.github.com/1068265.js?file=po_update.js" type="text/javascript"&gt;&lt;/script&gt;&lt;p&gt;The $pushAll operator atomically appends values onto an array attribute. Just as with our RDBMS scenario, this update is atomic and the whole command either succeeds or fails. Meanwhile the $inc operator atomically increments the “total” field of the purchase order. All of these updates happen atomically and they succeed or fail as a group so another client will never see an inconsistent state of the order.&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;It turns out that most of the time where you find yourself with a Master-Detail pattern in an RDBMS, you can achieve the same level of consistency in MongoDB by modelling your object as a rich, nested document, rather than multiple joined tables. Combine this with MongoDB’s atomic update operators, and you can solve most of what you would traditionally do with multi-statement transactions in an RDBMS.&lt;/p&gt;
&lt;p&gt;An RDBMS needs multi-statement transactions for these scenarios because the only way it has to model these types of objects is with multiple tables. By contrast, MongoDB can go much further with single-statement transactions because there’s no need to join on simple updates like this.&lt;/p&gt;
&lt;p&gt;This is not to say that multi-statement transactions are not useful. If you need to perform cross-entity transactions (e.g. move a line item from one purchase order to another) or if you need to modify a purchase order and inventory objects in a single step, then you may still need &lt;a href="http://www.mongodb.org/display/DOCS/two-phase+commit"&gt;multi-statement transactions&lt;/a&gt;. Or else you would have to take some &lt;a href="http://eaipatterns.com/ramblings/18_starbucks.html"&gt;alternate approach&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But it turns out that many of the cases where we traditionally need multi-statement transactions go away when we can model objects as documents and perform atomic updates on those documents.&lt;/p&gt;
&lt;p&gt;Another aspect of transactions and ACID is isolation. MongoDB does not support fully generalized snapshotting. We haven&amp;#8217;t discussed that here; it&amp;#8217;s probably a good topic for another blog post in the future.&lt;/p&gt;
&lt;p&gt;&amp;#8212; &lt;a href="http://jaredrosoff.com"&gt;Jared Rosoff&lt;/a&gt; (&lt;a href="http://twitter.com/forjared"&gt;@forjared&lt;/a&gt;)&lt;/p&gt;</description><link>http://blog.mongodb.org/post/7494240825</link><guid>http://blog.mongodb.org/post/7494240825</guid><pubDate>Mon, 11 Jul 2011 11:17:00 -0400</pubDate></item><item><title>Design of the Erlang Driver for MongoDB</title><description>&lt;p&gt;Since November 2010, I have been writing an &lt;a href="https://github.com/TonyGen/mongodb-erlang"&gt;Erlang driver for MongoDB&lt;/a&gt;. After many months of work, I would consider the driver production-ready, and wanted to take this opportunity to introduce the driver and highlight a few of the design decisions. For detailed documentation with code examples please see the links at the end of this article. &lt;br/&gt;&lt;br/&gt;&lt;strong&gt;BSON&lt;/strong&gt;&lt;br/&gt; At the highest level, the driver is divided into two library applications, &lt;a href="https://github.com/TonyGen/mongodb-erlang"&gt;mongodb&lt;/a&gt; and &lt;a href="https://github.com/TonyGen/bson-erlang"&gt;bson&lt;/a&gt;. BSON is defined independently of MongoDB at &lt;a href="http://bsonspec.org/"&gt;bsonspec.org&lt;/a&gt;.&lt;!-- more --&gt; One design decision was how to represent BSON documents in Erlang. Conceptually, a document is a record, but unlike an Erlang record, a BSON document does not have a single type tag. Furthermore, the same MongoDB collection can hold different types of records. So I decided to represent a BSON document as a tuple with labels interleaved with values, as in &lt;code&gt;{name, &amp;lt;&amp;lt;"Tony"&amp;gt;&amp;gt;, city, &amp;lt;&amp;lt;"New York"&amp;gt;&amp;gt;}&lt;/code&gt;. An alternative would have been to represent a document as a list of label-value pairs, but I wanted to reserve lists for BSON arrays. &lt;br/&gt;&lt;br/&gt; A BSON value is one of several types. One of these types is the document type itself, making it recursive. Several value types are not primitive, like objectId and javascript, so I had to define a tagged tuple type for each of them. I defined them all to have an odd number of elements to distinguish them from a document which has an even number of elements. For example, a javascript value looks like &lt;code&gt;{javascript, {x,2}, &amp;lt;&amp;lt;"x + 1"&amp;gt;&amp;gt;}&lt;/code&gt;. Finally, to distinguish between a string and a list of integers, which is indistinguishable in Erlang, I require BSON strings to be binary (UTF-8). Therefore, a plain Erlang string is interpreted as a BSON array of integers, so make sure to always encode your strings, as in &lt;code&gt; &amp;lt;&amp;lt;"hello"&amp;gt;&amp;gt; &lt;/code&gt; or &lt;code&gt;bson:utf8("hello")&lt;/code&gt; &lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Var&lt;/strong&gt;&lt;br/&gt; The mongodb driver has a couple of objects like connection and cursor that maintain mutable state. The only way to mutate state in Erlang is to have a process that maintains its own state that it updates when it receives messages from other processes. The Erlang programmer typically creates a process for each mutable object and defines the messages it may receive and the action to take for each message. They usually provide helper functions for the clients to call that hide the actual messages being sent and returned. Erlang OTP provides a small framework called &lt;em&gt;gen_server&lt;/em&gt; to facilitate this process definition but it is still non-trivial. To alleviate this burden I created another abstraction on top of gen_server called &lt;em&gt;var&lt;/em&gt;. A var is an object (process) that holds a value of some type A that may change. Its basic operation is &lt;code&gt;modify (var(A), fun ((A) -&amp;gt; {A, B})) -&amp;gt; B&lt;/code&gt; which applies the function to the current value of the var then changes the var&amp;#8217;s value to the first item of the result while returning the second item of the result to the client. This is done atomically thanks to the sequential nature of Erlang processes. The function may perform side effects (sending/receiving messages or doing IO), in which case the var acts like a mutex since only one function can execute against the var at a time. In essence, using var or even just gen_server changes the programming paradigm from message passing to protected shared state, which is more like Haskell for example. &lt;br/&gt;&lt;br/&gt; With &lt;code&gt;var&lt;/code&gt; it is now very easy to create objects that protect a shared resource or have internal mutable state. A TCP connection to a MongoDB server is one such resource that needs protection. The connection object in mongodb is implemented as a var holding a TCP connection. Every read and write operation gets exclusive access to the TCP connection when sending and receiving its messages to and from the server. This allows multiple user processes to read and write to the same mongodb connection concurrently. &lt;br/&gt;&lt;br/&gt;&lt;strong&gt;DB Action&lt;/strong&gt;&lt;br/&gt; Every read/write operation may throw a DB exception. Furthermore, every read/write operation requires a DB context that includes the connection to use, the database to access, whether slave is ok (read_mode), and whether to confirm writes (write_mode). We group a series of read/write operations that perform a single high-level task into a function called a &lt;em&gt;DB action&lt;/em&gt;. We then execute the action within a single exception handler and with a single DB context in dynamic scope (using Erlang&amp;#8217;s process dictionary). &lt;code&gt;mongo:do (write_mode(), read_mode(), connection(), db(), action(A)) -&amp;gt; {ok, A} | {failure, failure()}&lt;/code&gt; sets up the context, runs the action, and catches and returns any DB failure. Note, it will not catch and return other types of exceptions like programming errors. &lt;br/&gt;&lt;br/&gt; You may notice that a DB action is analogous to a DB transaction for a relational database in that the action aborts when one of its operations fails. However, for scalability reasons, MongoDB does not support ACID across multiple read/write operations, so the operations before the failed operation remain in effect. Your failure handler must be prepared to recover from this intermediate state. If your DB action is conceptually a single high-level task, then it should not be too hard to undo and redo that task even from an intermediate state. &lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;br/&gt; Detailed documentation with examples can be found in the ReadMe&amp;#8217;s of the two libraries, &lt;a href="https://github.com/TonyGen/mongodb-erlang"&gt;mongodb&lt;/a&gt; and &lt;a href="https://github.com/TonyGen/bson-erlang"&gt;bson&lt;/a&gt;, and in their source code comments and test modules. &lt;br/&gt;&lt;br/&gt; - &lt;a href="mailto:tony@10gen.com"&gt;Tony Hannan&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.mongodb.org/post/7270427645</link><guid>http://blog.mongodb.org/post/7270427645</guid><pubDate>Tue, 05 Jul 2011 14:27:00 -0400</pubDate></item><item><title>Getting started with VMware CloudFoundry, MongoDB and Node.js</title><description>&lt;p&gt;&lt;em&gt;Listen to the recording of the &lt;a href="http://www.10gen.com/webinars/nodejs"&gt;Node.js Panel Discussion webinar&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;div id="overview"&gt;
&lt;p&gt;&lt;strong&gt; Overview&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Following up from our &lt;a href="http://blog.mongodb.org/post/4719358003"&gt;previous post&lt;/a&gt; we&amp;#8217;re posting up a quick how-to for using &lt;a href="http://nodejs.org"&gt;Node.JS&lt;/a&gt;, &lt;a href="http://www.cloudfoundry.com"&gt;CloudFoundry&lt;/a&gt; and &lt;a href="http://www.mongodb.org"&gt;MongoDB&lt;/a&gt; together.&lt;/p&gt;
&lt;p&gt;Our end goal here is to build a simple web app that records visits and provides a reporting screen for the last 10 visits.&lt;!-- more --&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div id="tools_we_need"&gt;
&lt;p&gt;&lt;strong&gt; Tools We Need&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;a href="http://cloudfoundry.com/signup"&gt;Sign up for a Cloud Foundry account&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/Quickstart"&gt;Local installation of MongoDB&lt;/a&gt; &amp;amp; &lt;a href="https://github.com/joyent/node/wiki/Installation"&gt;Node.JS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Cloud Foundry &lt;a href="http://support.cloudfoundry.com/entries/20012337-getting-started-guide-command-line-vmc-users"&gt;VMC tools&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;All of the code is available on &lt;a href="https://github.com/gatesvp/cloudfoundry_node_mongodb"&gt;github&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;Follow the links to install &amp;amp; configure the various tools.&lt;/div&gt;
&lt;div id="getting_started"&gt;
&lt;p&gt;&lt;strong&gt; Getting Started&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Start the &lt;code&gt;mongod&lt;/code&gt; process on your local computer. Use the default port.&lt;/li&gt;
&lt;li&gt;Confirm that node.js is correctly installed. You should be able to run &lt;code&gt;node&lt;/code&gt; from the command-line and receive a basic javascript shell. You should also have NPM (node package manager) installed.&lt;/li&gt;
&lt;li&gt;Make a directory for the project and then ensure that CloudFoundry is correctly configured. Mine looked as follows:&lt;/li&gt;
&lt;/ol&gt;&amp;lt;pre &amp;gt; mongo@ubuntu:~$ sudo gem install vmc mongo@ubuntu:~$ vmc target api.cloudfoundry.com Succesfully targeted to [http://api.cloudfoundry.com] mongo@ubuntu:~$ vmc login Email: gates@10gen.com Password: ******** Successfully logged into [http://api.cloudfoundry.com]&lt;/div&gt;
&lt;div id="step_1"&gt;
&lt;p&gt;&lt;strong&gt; Step 1: Hello world&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In your directory create a file called &lt;a href="https://github.com/gatesvp/cloudfoundry_node_mongodb/blob/master/app.js.1"&gt;&lt;code&gt;app.js&lt;/code&gt;&lt;/a&gt;. In that file, type the following code. This will create a basic web server on localhost:3000 or on the assigned host:port combination on the CloudFoundry server.&lt;/p&gt;
&lt;pre&gt;var port = (process.env.VMC_APP_PORT || 3000);
var host = (process.env.VCAP_APP_HOST || 'localhost');
var http = require('http');

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(port, host);
&lt;/pre&gt;
&lt;p&gt;Test our file locally:&lt;/p&gt;
&lt;pre&gt;$ node app.js
$ curl localhost:3000
Hello World
# kill node with CTRL+C
&lt;/pre&gt;
&lt;p&gt;Push our file to CloudFoundry and test. CloudFoundry automatically picks up that we&amp;#8217;re using node.js,but it will ask some other configuration questions, including a name and the services we want to have running. I have named mine &lt;code&gt;gvp_node_test&lt;/code&gt; and requested that MongoDB be run as a service.&lt;/p&gt;
&lt;p&gt;The commands &amp;amp; output:&lt;/p&gt;
&lt;pre&gt;$ vmc push 
Would you like to deploy from the current directory? [Yn]: Y
Application Name: gvp_node_test
Application Deployed URL: 'gvp_node_test.cloudfoundry.com'? 
Detected a Node.js Application, is this correct? [Yn]: Y
Memory Reservation [Default:64M] (64M, 128M, 256M, 512M, 1G or 2G) 
Creating Application: OK
Would you like to bind any services to 'gvp_node_test'? [yN]: y
The following system services are available::
1. mongodb
2. mysql
3. redis
Please select one you wish to provision: 1
Specify the name of the service [mongodb-55516]: 
Creating Service: OK
Binding Service: OK
Uploading Application:
  Checking for available resources: OK
  Packing application: OK
  Uploading (0K): OK   
Push Status: OK
Staging Application: OK                                                         
Starting Application: OK                                       
&lt;/pre&gt;
&lt;p&gt;At this point you should have a simple working web app. Note the URL: &lt;code&gt;your_app_name.cloudfoundry.com&lt;/code&gt;, we can test it is working with &lt;code&gt;curl&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;$ curl your_app_name.cloudfoundry.com
Hello World
&lt;/pre&gt;
&lt;/div&gt;
&lt;div id="step_2"&gt;
&lt;p&gt;&lt;strong&gt; Step 2: getting mongo configs &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;CloudFoundry has now configured a MongoDB service with its own user name, password, ip and port. To access these on the server, we will need to parse the environment variables coming into the &lt;code&gt;node&lt;/code&gt; process.&lt;/p&gt;
&lt;p&gt;To do this we do the following, note that we&amp;#8217;ve added an &lt;code&gt;else&lt;/code&gt; clause so that we can run this locally.&lt;/p&gt;
&lt;pre&gt;if(process.env.VCAP_SERVICES){
  var env = JSON.parse(process.env.VCAP_SERVICES);
  var mongo = env['mongodb-1.8'][0]['credentials'];
}
else{
  var mongo = {"hostname":"localhost","port":27017,"username":"",
    "password":"","name":"","db":"db"}
}
&lt;/pre&gt;
&lt;p&gt;The &lt;a href="https://github.com/gatesvp/cloudfoundry_node_mongodb/blob/master/app.js.2"&gt;code&lt;/a&gt; wraps this up in a &lt;code&gt;generate_mongo_url&lt;/code&gt; function that provides a &amp;#8220;connection string&amp;#8221; of the form &lt;code&gt;mongodb://username:password@host:port/db_name&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Copy in the rest of the code from step 2 on github and test locally.&lt;/p&gt;
&lt;pre&gt;$ node app.js
$ curl localhost:3000
# connection string for localhost
&lt;/pre&gt;
&lt;p&gt;Once that&amp;#8217;s working push the update to the cloud. Notice that we add the name of the project and we don&amp;#8217;t get asked any questions:&lt;/p&gt;
&lt;pre&gt;$ vmc update your_app_name
Uploading Application:
...
Stopping Application: OK
Staging Application: OK                                                         
Starting Application: OK 
# test again
$ curl your_app_name.cloudfoundry.com
# bunch of environment variables
&lt;/pre&gt;
&lt;/div&gt;
&lt;div id="step_3"&gt;
&lt;p&gt;&lt;strong&gt; Step 3: now with drivers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First we need to install the &lt;code&gt;node-mongodb-native&lt;/code&gt; driver. To do this, we use NPM.&lt;/p&gt;
&lt;pre&gt;$ npm install mongodb
&lt;/pre&gt;
&lt;p&gt;You should see a new directory at the end of this process: &lt;code&gt;node_modules&lt;/code&gt;. To enable use to include these module on the cloud we add this path to the &lt;code&gt;require&lt;/code&gt; variable at the top of the code.&lt;/p&gt;
&lt;pre&gt;require.paths.unshift('./node_modules');

if(process.env.VCAP_SERVICES){
...
&lt;/pre&gt;
&lt;p&gt;Our goal here is to build a function for recording a visit. Let&amp;#8217;s build that function.&lt;/p&gt;
&lt;pre&gt;var record_visit = function(req, res){
  /* Connect to the DB and auth */
  require('mongodb').connect(mongourl, function(err, conn){
    conn.collection('ips', function(err, coll){
      /* Simple object to insert: ip address and date */
      object_to_insert = { 'ip': req.connection.remoteAddress, 'ts': new Date() };

      /* Insert the object then print in response */
      /* Note the _id has been created */
      coll.insert( object_to_insert, {safe:true}, function(err){
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.write(JSON.stringify(object_to_insert));
        res.end('\n');
      });
    });
  });
}
&lt;/pre&gt;
&lt;p&gt;Notice the &lt;code&gt;.connect&lt;/code&gt; and &lt;code&gt;.collection('ips'...)&lt;/code&gt;. We&amp;#8217;re telling it to store data in the &lt;code&gt;ips&lt;/code&gt; collection.&lt;/p&gt;
&lt;p&gt;Another nice feature is the &lt;code&gt;object_to_insert&lt;/code&gt;. Saving a document with Node+MongoDB is as simple as creating the object and inserting it.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s fix up the main &lt;code&gt;createServer&lt;/code&gt; function.&lt;/p&gt;
&lt;pre&gt;http.createServer(function (req, res) {
  record_visit(req, res);
}).listen(port, host);
&lt;/pre&gt;
&lt;p&gt;Then we can test locally and push with &lt;code&gt;vmc&lt;/code&gt;. If this is working locally, you should be able to connect to your local mongod instance and see some data in the &lt;code&gt;ips&lt;/code&gt; collection.&lt;/p&gt;
&lt;pre&gt;$ mongo localhost:27017/db
&amp;gt; db.ips.find()
...
&lt;/pre&gt;
&lt;/div&gt;
&lt;div id="step_4"&gt;
&lt;p&gt;&lt;strong&gt; Step 4&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;At this point, you&amp;#8217;ve probably tested a few times and you&amp;#8217;ve successfully put data in the database. Now it&amp;#8217;s time to get that data out.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s create a function to print the last 10 visits:&lt;/p&gt;
&lt;pre&gt;var print_visits = function(req, res){
  /* Connect to the DB and auth */
  require('mongodb').connect(mongourl, function(err, conn){
    conn.collection('ips', function(err, coll){
      /*find with limit:10 &amp;amp; sort */
      coll.find({}, {limit:10, sort:[['_id','desc']]}, function(err, cursor){
        cursor.toArray(function(err, items){
          res.writeHead(200, {'Content-Type': 'text/plain'});
          for(i=0; i &amp;lt; items.length; i++){
            res.write(JSON.stringify(items[i]) + "\n");
          }
          res.end();
        });
      });
    });
  });
}
&lt;/pre&gt;
&lt;p&gt;Let&amp;#8217;s update the &lt;code&gt;createServer&lt;/code&gt; method to print when we request &lt;code&gt;/history&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;http.createServer(function (req, res) {
  params = require('url').parse(req.url);
  if(params.pathname === '/history') {
    print_visits(req, res);
  }
  else{
    record_visit(req, res);
  }
}).listen(port, host);
&lt;/pre&gt;
&lt;p&gt;Again, we test locally and then upload with &lt;code&gt;vmc&lt;/code&gt;. If it all works, you should be able to do this:&lt;/p&gt;
&lt;pre&gt;$ vmc update your_app_name
...
$ curl your_app_name.cloudfoundry.com
{"ip":"172.30.49.42","ts":"2011-06-15T20:14:18.977Z","_id":"4df9129af354f8682d000001"}
$ curl your_app_name.cloudfoundry.com
{"ip":"172.30.49.43","ts":"2011-06-15T20:14:21.745Z","_id":"4df9129df354f8682d000002"}

# now let's test history
$ curl gvp_node_test.cloudfoundry.com/history
{"ip":"172.30.49.43","ts":"2011-06-15T20:14:21.745Z","_id":"4df9129df354f8682d000002"}
{"ip":"172.30.49.42","ts":"2011-06-15T20:14:18.977Z","_id":"4df9129af354f8682d000001"}
...
&lt;/pre&gt;
&lt;/div&gt;
&lt;div id="going_further"&gt;
&lt;p&gt;&lt;strong&gt; Going further&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Check out our upcoming &lt;a href="http://www.10gen.com/webinars/nodejs"&gt;Node.js Panel Discussion webinar&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;For some MongoDB wrappers take a look at
&lt;ul&gt;&lt;li&gt;&lt;a href="http://mongoosejs.com"&gt;Mongoose&lt;/a&gt;, an ORM / ODM wrapper&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/craftgear/node-mongoskin"&gt;MongoSkin&lt;/a&gt;, a layer over node-mongodb-native to help reduce callbacks.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;For building more complex web sites take a look at the &lt;a href="http://expressjs.com"&gt;Express framework&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
&lt;p&gt;&amp;#8212; Gates Voyer-Perrault&lt;br/&gt; @gatesvp&lt;/p&gt;</description><link>http://blog.mongodb.org/post/6587009156</link><guid>http://blog.mongodb.org/post/6587009156</guid><pubDate>Thu, 16 Jun 2011 10:00:00 -0400</pubDate><category>mongodb</category><category>nosql</category><category>javascript</category><category>nodejs</category><category>node.js</category></item><item><title>A reminder about MongoDB "office hours"</title><description>&lt;p&gt;Very casual whiteboard type chat sessions on a regular basis in SF, NYC, Redwood Shores, Mountain View, and Atlanta.  &lt;a href="http://www.10gen.com/officehours"&gt;Stop by!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also check out the &lt;a href="http://www.meetup.com/find/?keywords=mongoDB&amp;amp;mcId=&amp;amp;mcName=&amp;amp;lat=&amp;amp;lon=&amp;amp;userFreeform=&amp;amp;gcResults=&amp;amp;op=search&amp;amp;resetgeo=true&amp;amp;events=&amp;amp;submitButton=Search"&gt;meetup users groups&lt;/a&gt; in lots of other cities.&lt;/p&gt;</description><link>http://blog.mongodb.org/post/6320979730</link><guid>http://blog.mongodb.org/post/6320979730</guid><pubDate>Wed, 08 Jun 2011 11:21:00 -0400</pubDate></item></channel></rss>

