MongoHQ

This add-on is operated by MongoHQ, Inc

Hosted, optimized and super-fast MongoDB databases.

MongoHQ

Last Updated: 20 February 2014

database java mongodb nosql

Table of Contents

MongoDB is a document-oriented data store. For more information about MongoDB, visit: http://www.mongodb.org.

MongoHQ is a cloud-based hosted database solution that allows developers to easily deploy, manage and scale both single and replica set MongoDB databases for their web and mobile applications. Our fast and reliable databases allow you to focus on developing your app while our team focuses on making your database fast and highly available.

Adding a MongoHQ database

To add a MongoHQ database to your Heroku application (using your console), simply install the MongoHQ Add-on, specifying the plan that you desire. For example:

You can also add a MongoHQ database if you are logged into the Heroku web site. Click on “Add-on Resources” for your app and select the plan you would like to use.

$ heroku addons:add mongohq:small

This command provisions a small (2GB) database on the MongoHQ platform and updates your Heroku configs with an environment variable called MONGOHQ_URL. This variable will be assigned a connection string which includes all your server information as well as automatically-generated user/pass authentication to your database.

The environment variable and string will look like:

MONGOHQ_URL: mongodb://<user>:<pass>@hatch.mongohq.com:10034/app003132345

Now, you can use the MONGOHQ_URL variable in code and configurations for your driver, depending on the language you app is created in, connecting and authenticating to your MongoDB database hosted with MongoHQ. We provide some examples of the use of this variable in the topics to follow.

Most of the various languages have an “official” driver as well as ORMs (Object-Relational Mappers) that you can use, depending on the type of implementation that you would like. This documentation will try to cover the most popular of each of these.

Use with Ruby

Assuming you are using Ruby 1.9 or greater, you will only need the mongo gem to get started. For optimal performance, you can include the bson_ext gem as well. So, from console, make sure the following drivers are installed:

$ gem install mongo
$ gem install bson_ext

In your connection file, you can parse out the connection string by doing the following:

If you are using 1.8 versions of Ruby, there are subtle changes you will need to make to your required gems. Check the docs link below for more information.

require 'mongo'
require 'uri'

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

Now you should have an established connection to your database. If you want to test this, you could output a listing of the collections of your Mongo database by doing this:

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

If you have not placed anything in your database, it should show just two collections … system.users and system.indexes. From here, you can now start accessing documents, indexes and more … making changes and updates, etc. For more information about the Mongo Ruby Driver and its capabilities, visit: http://api.mongodb.org/ruby/current/file.TUTORIAL.html

Mongoid (Ruby/MongoDB ORM)

Mongoid is an extremely popular Object-Document Mapper (ODM) created for the Ruby and MongoDB community. It benefits from wide adoption as well as solid community support. It is the tool of choice for the developers at MongoHQ as well.

Mongoid has main versions now … 2.x and 3.x. The 2.x versions are in wide use, while the 3.x versions are slowly being incorporated into applications. For now, we will include documentation for both.

Mongoid 2.x

First things first … make sure that you have the right gem installed.

We’re big fans of Bundler, so even though we don’t include Bundler syntax here, feel free to use it. :)

$ gem install mongoid -v 2.4.12

Now that the gem is installed, the next step is to configure Mongoid to work with your MongoHQ database provisioned through Heroku. Mongoid uses a YAML file to achieve this. Add a mongoid.yml file to your application. If this is Rails, it is normally stored in the config directory of your app.

Your mongoid.yml should look like:

production:
  uri: <%= ENV['MONGOHQ_URL'] %>

That’s it. Pretty simple.

There are additional configuration options that are available. We recommend a configuration that uses the following options:

persist_in_safe_mode turns on “safe writes” for the driver. In general, this is best practice.

production:
  uri: <%= ENV['MONGOHQ_URL'] %>
  max_retries_on_connection_failure: 20
  persist_in_safe_mode: true
  skip_version_check: true

This should get you fully connected. From here, its up to you to learn about MongoDB and the Mongoid driver. Full documentation for Mongoid 2.x is located here: http://two.mongoid.org/.

If you are using Mongoid 3.x and Moped on Heroku, make sure your app is upgraded to Ruby 1.9.3 and utilizing the Cedar Celedon stack.

Mongoid 3.x

Ensure that you have the mongoid gem installed … not declaring the version will make sure that you have the latest 3.x release of the code.

$ gem install mongoid

Now that the gem is installed, the next step is to configure Mongoid to work with your MongoHQ database provisioned through Heroku. Mongoid uses a YAML file to achieve this. Add a mongoid.yml file to your application. If this is Rails, it is normally stored in the config directory of your app.

Your mongoid.yml should look like:

Check out the Mongoid 3.x documentation for more information about the new “sessions” syntax and how it is used.

production:
  sessions:
    default:
      uri: <%= ENV['MONGOHQ_URL'] %>

That’s it. To learn more about sessions, please review the Mongoid 3.x documentation.

There are additional configuration options that are available through mongoid. We recommend a configuration that uses the following options:

production:
  sessions:
    default:
      uri: <%= ENV['MONGOHQ_URL'] %>
      options:
        skip_version_check: true
        safe: true

This should get you fully connected. From here, its up to you to learn about MongoDB and the Mongoid driver. Full documentation for Mongoid 3.x is located here: http://www.mongoid.org/.

Mongoid and replica sets

Mongoid actually makes configuring replica sets quite easy … one of the cleanest implementations of all the drivers. It, of course, all happens in the mongoid.yml file.

Currently, when a replica set is deployed through the Add-on, it does not include both members of the set, only the member0. Therefore, you have to parse your MONGOHQ_URL or hard-code each member into your mongoid.yml file.

Here is how a typical mongoid.yml file for Mongoid 2.x would look:

As noted, in this example (and the below Mongoid 3.x example), you will need to parse out your MONGOHQ_URL Heroku config variable. Check out the get_connection method in the earlier Ruby example for tips on how to do this.

production:
  hosts:
    - - <hostname>.member0.mongohq.com
      - <port_number>
    - - <hostname>.member1.mongohq.com
      - <port_number>
  username: <username>
  password: <password>
  database: <database_name>
  max_retries_on_connection_failure: 20
  persist_in_safe_mode: true
  skip_version_check: true

With both of these configurations, we have “safe mode” turned on. Slower performance, but it will throw an error if it cannot write. Alter this for what suits you best.

Here is how a typical mongoid.yml file for Mongoid 3.x would look:

production:
  sessions:
    default:
      hosts:
        - - <hostname>.member0.mongohq.com
          - <port_number>
        - - <hostname>.member1.mongohq.com
          - <port_number>
      username: <username>
      password: <password>
      database: <database>
      options:
        skip_version_check: true
        safe: true

The big thing to note from this documentation is that all that changes are the member0 and member1 in the host names. The ports remain the same as well as the remainders of the connection strings.

MongoMapper (Ruby/MongoDB ORM)

MongoMapper (created by John Nunemaker of Github) is, similar to Mongoid, an Object Mapper. However, that is where the similarity ends. If you enjoy the comfort and syntax that ActiveRecord affords you, then MongoMapper will closely match that experience. When MongoDB was first on the scene, MongoMapper became quite popular for this reason.

It is important to remember that MongoMapper acts like a replacement to ActiveRecord. Given that, you need to change a couple of configurations to how a standard Rails app works.

To get started with MongoMapper and Rails 3, do the following:

First, update your config/application.rb from:

   require 'rails/all'

to

  require "action_controller/railtie"
  require "action_mailer/railtie"
  require "active_resource/railtie"
  require "rails/test_unit/railtie"
  # Uncomment for asset pipelining in Rails 3.1
  # require "sprockets/railtie"

Now, the next step is to add MongoMapper to your Gemfile and run bundle install.

  gem 'mongo_mapper'
  gem 'bson_ext'

Finally, you’ll need some configuration information. To generate config/mongo.yml, do this:

script/rails generate mongo_mapper:config

Now that all your configuration is proper, you need to connect your MongoHQ database to your Rails app. Doing this is easy with your mongo.yml file. Change your settings to:

  production:
    uri: <%= ENV['MONGOHQ_URL'] %>

That’s it. You should be ready to go. One more MongoMapper-specific change that you may want to consider is configuring the Rails Model generator to work with MongoMapper. To do this, add the following inside the Application class of your config/application.rb.

  config.generators do |g|
    g.orm :mongo_mapper
  end

If you are interested in learning more about MongoMapper before fully integrating it into your application, check out the MongoMapper Console, as it provides a great way to discover more about MongoMapper.

Finally, while it is a bit dated now, you can still view Ryan Bates' screencast called MongoDB and MongoMapper if you are interested in a step-by-step guide. As you can imagine, some of the functionality in this video is deprecated by now.

Full documentation for MongoMapper is located here: http://mongomapper.com/.

Use with Java

MongoDB offers a standard Java client. In order to use this client in your project, you have to declare the dependency in your build and initialize the connection from the environment variable that we highlighted in the Adding a MongoHQ Database section above.

Add the Mongo Java driver to your pom.xml

Add the following dependency to your pom.xml:

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongo-java-driver</artifactId>
    <version>2.7.2</version>
</dependency>

Use MongoDB in your application

URI mongoURI = new URI(System.getenv("MONGOHQ_URL"));

MongoURI mongoURI = new MongoURI(System.getenv("MONGOHQ_URL"));
DB db = mongoURI.connectDB();
db.authenticate(mongoURI.getUsername(), mongoURI.getPassword());

//Use the db object to talk to MongoDB
Set<String> colls = db.getCollectionNames();

Using MongoDB with Spring

Use the following Java Configuration class to set up a DB object as a singleton Spring bean:

@Configuration
public class SpringConfig {
    @Bean
    public DB getDb() throws UnknownHostException, MongoException {
        MongoURI mongoURI = new MongoURI(System.getenv("MONGOHQ_URL"));
        DB db = mongoURI.connectDB();
        db.authenticate(mongoURI.getUsername(), mongoURI.getPassword());

        return db;
    }
}

or the following XML configuration file:

MethodInvokingFactoryBean is used to initialize beans using methods other than constructors and setters.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config/>
    <context:property-placeholder/>

    <bean id="mongoURI" class="com.mongodb.MongoURI">
      <constructor-arg value="${MONGOHQ_URL}"/>
    </bean>

    <!-- create db object by calling getDB on mongo bean -->
    <bean id="db" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
      <property name="targetObject"><ref local="mongoURI"/></property>
      <property name="targetMethod"><value>connectDB</value></property>
    </bean>

    <!-- call authenticate on db object -->
    <bean id="authenticateDB"
        class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject"><ref local="db" /></property>
        <property name="targetMethod">
            <value>authenticate</value>
        </property>
        <property name="arguments">
            <list>
                <value>#{ @mongoURI.getUsername() }</value>
                <value>#{ @mongoURI.getPassword() }</value>
            </list>
        </property>
    </bean>
</beans>

Sample code

To see a complete, working example, check out the sample code in github. The readme explains more about the example.

MongoHQ replica sets

MongoHQ provides multi-zone data redundancy and availability through MongoDB Replica Sets. Currently, when Heroku generates the configs for a replica set database, it does not include the connection strings for both members. So, this requires a bit of handling on the part of the developer to ensure configurations and high-availability are truly available in their app.

In your configs, if you deploy a replica set plan, the member0 is normally included. However, there is also a member1 of the set as well and you need to make sure that your drivers are aware of it. While some drivers can auto-detect all the members of a set, they still need the full listing of members in their configuation.

If you need more assistance with this, please let us know.

Driver differences for replica sets

Please note that most drivers have very different configurations for replica sets. We will do our best, in this documentation, to highlight these differences, but make sure

Testing high availability

Once you have your driver settings for your replica set correct, but would like to simulate step downs to test the resilency of your application, please let us know at: support@mongohq.com. We are happy to schedule some time with you to walk through these tests. This way, you feel confident that, in the event of an issue, your database will remain available and online.

Custom and/or sharded Databases

We will have more information about this soon.

MongoHQ web tools

MongoHQ provides helpful web tools that allow to you query and interact with the data stored in your MongoDB database. To access your database using our web tools, we nave provided integration with your Heroku log in, allowing you to access our app using your Heroku credentials. To do this, you will need to:

  1. Log into your Heroku account.
  2. Once logged in, click on the appropriate app.
  3. Click on the dropdown labled “Add-Ons” in the top-right of the screen.
  4. Select MongoHQ.

Now that you are logged in, you can run queries, build indexes, add users, etc.

Upgrading your database

Heroku allows for only one database to be associated with each provisioned application on their platform. Therefore, since we actually move your data and update your connection string, the current upgrade process for non-replica-set databases requires a maintenance window to allow you move data from one database to another.

This exercise will only work if you have MongoDB installed on your local machine. If you need help, just ask!

To do this, use the following instructions. In this example, we will upgrade from a “sandbox” to a “small” database.

Please note: You will need your current MONGOHQ_URL (from your Heroku configs) available before you begin as the following steps will alter it permanently.

Take your application into maintenance mode.

$ heroku maintenance:on

Run a mongodump of your current database.

$ mongodump -h hostname.mongohq.com:port_number -d database_name -u username -p password -o /path/on/my/local/computer

Deprovision the old database for this app, making sure that the mongodump in Step #2 completed successfully.

$ heroku addons:remove mongohq:sandbox

Provision a new database for this app.

$ heroku addons:add mongohq:small

Make available the newly updated MONGOHQ_URL from your Heroku configs.

Run a mongorestore of your locally backed up database to your new database (updating your connection info.)

$ mongorestore -h hostname.mongohq.com:port_number -d database_name -u username -p password /path/on/my/computer/to/mongodump/db_name

Return from maintenance mode.

$ heroku maintenance:off

At this point, everything should be good. If you were properly relying on the MONGOHQ_URL in your application, then it should automatically reflect the changed database and everything should be working properly.

If you need any help in this process, please contact us. We are happy to assist.

Backups

We take (and maintain) daily snapshots of all databases hosted on the MongoHQ platform.

What if I have an issue?

If there is ever a serious issue or error and you need assistance, please contact MongoHQ Support at: support@mongohq.com.It is most helpful if you include the full MONGOHQ_URL in your heroku configs when you send us a note. That will ensure that we can act swiftly to restore data.

Can I back up my data to Amazon S3?

Due to current limitations with the Add-On Provider Program, we are unable to make our automated Amazon S3 backups available to developers that add databaes through Heroku. However, you can still set up a cron job that regularly runs a mongodump of your database (either to your local machine or another server).

Help!

Common Issues

All the sudden, I can’t authenticate to my database? Wat!

If your app can no longer authenticate to your database, it may mean that your system.users collection has been erased by a rake task. For example. if you run a task like rake db:reseed in Mongoid, it will remove database collections, including your system users. This will make you sad.

You can add a database user back by using the MongoHQ web UI (accessed through your app in Heroku) or reach out to us at support@mongohq.com and we can assist in recovering the users for you.

The password that the MongoHQ web tools displays is not working for me.

If you copied the displayed password in the MongoHQ web tools into your app, the authentication will fail because the web tools are actually displaying the hashed value of your password and not your actual password.

The password to your database was automatically created when you provisioned your MongoHQ database through Heroku. You can either use the MONGOHQ_URL in the uri value in your MongoDB driver configs or access your user name and password by running the following in your console:

  heroku config | grep "MONGOHQ"

Support

At MongoHQ, we have a talented and friendly team and are always happy to support you as you develop with Heroku and MongoDB. Feel free to reach out to us at: support@mongohq.com. Make sure to include the name of your database … it is your appID name.

Status Monitoring

For support requests, please contact Heroku Support using http://support.heroku.com. For status monitoring, please check Heroku Status at: http://status.heroku.com or MongoHQ Status at http://status.mongohq.com.

Additional documentation

Additional documentation, covering other topics about MongoHQ (as well as MongoDB) can be located at: http://support.mongohq.com.