Connect to MongoHQ

In the first of many posts to simplify connecting to MongoHQ, we’re providing sample code for many programming languages, frameworks and setups (replica sets, slaveOk, etc).

These examples all assume that your MongoHQ connection string is set in an environment variable MONGOHQ_URL, like this:

export MONGOHQ_URL=mongodb://user:pass@server.mongohq.com/db_name  

If you use any of our PaaS providers this environment variable should already be set when you choose the MongoHQ add-on. Or you can set it yourself using whatever mechanism the Paas allows. For example, in Heroku:

heroku config:add MONGOHQ_URL=mongodb://...  

Today I’ll roll out PHP, two NodeJS (JS and Coffee), and Ruby snippets. In every case we use the basic driver to connect (no frameworks like CakePHP or Mongoid–those will come later).

PHP Connection to MongoHQ

This originally began as a Gist from Larry Hitchon of AppFog. I fixed it up a bit and made it MongoHQ-centric. It’s a pretty straightforward driver. If you don’t have PECL, you should install PECL.

sudo pecl install mongo  
<!-- PHP Mongo Docs: http://php.net/manual/en/class.mongodb.php -->  
<html>  
<body>  
<h1>MongoHQ Test</h1>  
<?php  
  try {
    // connect to MongoHQ assuming your MONGOHQ_URL environment
    // variable contains the connection string
    $connection_url = getenv("MONGOHQ_URL");

    // create the mongo connection object
    $m = new Mongo($connection_url);

    // extract the DB name from the connection path
    $url = parse_url($connection_url);
    $db_name = preg_replace('/\/(.*)/', '$1', $url['path']);

    // use the database we connected to
    $db = $m->selectDB($db_name);

    echo "<h2>Collections</h2>";
    echo "<ul>";

    // print out list of collections
    $cursor = $db->listCollections();
    $collection_name = "";
    foreach( $cursor as $doc ) {
      echo "<li>" .  $doc->getName() . "</li>";
      $collection_name = $doc->getName();
    }
    echo "</ul>";

    // print out last collection
    if ( $collection_name != "" ) {
      $collection = $db->selectCollection($collection_name);
      echo "<h2>Documents in ${collection_name}</h2>";

      // only print out the first 5 docs
      $cursor = $collection->find();
      $cursor->limit(5);
      echo $cursor->count() . ' document(s) found. <br/>';
      foreach( $cursor as $doc ) {
        echo "

{gfm-js-extract-pre-1}";
      }
    }

    // disconnect from server
    $m->close();
  } catch ( MongoConnectionException $e ) {
    die('Error connecting to MongoDB server');
  } catch ( MongoException $e ) {
    die('Mongo Error: ' . $e->getMessage());
  } catch ( Exception $e ) {
    die('Error: ' . $e->getMessage());
  }
?>
</body>  
</html>  

NodeJS Connection to MongoHQ (JavaScript)

This code uses the node-mongodb-native driver, though in production you may want something a little less… nesty. Like all good Node packages, you can get it via NPM.

npm install mongodb  
// npm install mongodb
var mongodb = require('mongodb');  
var url = require('url');  
var log = console.log;

var connectionUri = url.parse(process.env.MONGOHQ_URL);  
var dbName = connectionUri.pathname.replace(/^\//, '');

mongodb.Db.connect(process.env.MONGOHQ_URL, function(error, client) {  
  if (error) throw error;

  client.collectionNames(function(error, names){
    if(error) throw error;

    // output all collection names
    log("Collections");
    log("===========");
    var lastCollection = null;
    names.forEach(function(colData){
      var colName = colData.name.replace(dbName + ".", '')
      log(colName);
      lastCollection = colName;
    });

    var collection = new mongodb.Collection(client, lastCollection);
    log("\nDocuments in " + lastCollection);
    var documents = collection.find({}, {limit:5});

    // output a count of all documents found
    documents.count(function(error, count){
      log("  " + count + " documents(s) found");
      log("====================");

      // output the first 5 documents
      documents.toArray(function(error, docs) {
if(error) throw error;

docs.forEach(function(doc){  
  log(doc);
});

// close the connection
client.close();  
      });
    });
  });
});

NodeJS Connection to MongoHQ (CoffeeScript)

(Side note… I love coffeescript)

# npm install mongodb
mongodb = require 'mongodb'  
url = require 'url'  
log = console.log

connection_uri = url.parse(process.env.MONGOHQ_URL)  
db_name = connection_uri.pathname.replace(/^\//, '')

mongodb.Db.connect process.env.MONGOHQ_URL, (error, client)->  
  throw error if error

  client.collectionNames (error, names)->
    throw error if error

    # output all collection names
    log "Collections"
    log "==========="
    last_collection = null
    for col_data in names
      col_name = col_data.name.replace("#{db_name}.", '')
      log col_name
      last_collection = col_name

    collection = new mongodb.Collection(client, last_collection)
    log "\nDocuments in #{last_collection}"
    documents = collection.find({}, limit : 5)

    # output a count of all documents found
    documents.count (error, count)->
      log "  #{count} documents(s) found"
      log "===================="

      # output the first 5 documents
      documents.toArray (error, docs)->
throw error if error

for doc in docs then log doc

# close the connection

client.close()  

Ruby Connection to MongoHQ

We wrap up today by connecting Ruby to MongoHQ. To get started, install the mongo gem. If you want more speed, install the native bson_ext, and if you are in less than Ruby 1.9, you’ll need the json gem. It should go without saying, but you will need RubyGems.

gem install mongo bson_ext json  
# gem install mongo bson_ext json
require 'rubygems'  # if less than Ruby 1.9  
require 'mongo'  
require 'uri'  
require 'json'

def get_connection  
  return @db_connection if @db_connection
  db = URI.parse(ENV['MONGOHQ_URL'])
  db_name = db.path.gsub(/^\//, '')
  @db_connection = Mongo::Connection.new(db.host, db.port).db(db_name)
  @db_connection.authenticate(db.user, db.password) unless (db.user.nil? || db.user.nil?)
  @db_connection
end

db = get_connection

puts "Collections"  
puts "==========="  
collections = db.collection_names  
puts collections

last_collection = collections[-1]  
coll = db.collection(last_collection)

# just show 5

docs = coll.find().limit(5)

puts "\nDocuments in #{last_collection}"  
puts "  #{docs.count()} documents(s) found"  
puts "=========================="  
docs.each{ |doc| puts doc.to_json }  

Part 2 will be Python and Java, and maybe more.