A lightweight ORM for Rails and MongoDB
Pull request Compare This branch is 3 commits ahead of karlseguin:master.
Failed to load latest commit information.
lib Added index support, currently no tests and doesn't support aliases Oct 16, 2012
.gitignore Added some common things to ignore Oct 12, 2012
Gemfile Updated Gemfile to support all the gems required to get the test suit… Oct 12, 2012
Gemfile.lock Updated Gemfile to support all the gems required to get the test suit… Oct 12, 2012



MongoLight is a lightweight object-relational mapper for Rails and MongoDB. It is not ActiveRecord compatible. Rather, the primary purpose is to be a thin wrapper around the excellent core MongoDB driver.

The only Rails dependency is on ActiveSupport::Concern.

The wrapper fits a specific use-case (mine).


Configure MongoLight via MongoLight.configure:

MongoLight.configure do |config|
  config.connection = Mongo::Connection.new
  config.database = 'mongolight_tests'

This'll automatically handle Passenger forking issues (if Passenger is running).

replica concern and testing

For safe writes, I like to use w:majority. However, MongoDB will raise an exception if you use this while not using replica sets. This can make testing code more of a pain than necessary. If you configure MongoLight with config.skip_replica_concern = true, then :w => X or :w => :majority will automatically be stripped when calling save(:w => majority) or save!(:w => 3). (For example, you could do config.skip_replica_concern = Rails.env.test?)


To define a document include MongoLight::Document and define your properties using the mongo_accessor method:

class User
    include MongoLight::Document
    mongo_accessor({:name => :name, password => :pw, :email => :e})

Within your code, you can access the name, password and email properties. However, internally, MongoDB will store the fields as name, pw and e (document databases store the field names with each document, this can save a lot of space (we saved 25%)).


Experimental: currently doesn't support alias names and theres no tests

class User
    include MongoLight::Document
    mongo_accessor({ :name => :n, :email => :e })
    index([:e, -1], { unique: true })

Document Manipulation

Most of what you can do on a MongoDB collection (again, the Ruby driver), you can do on a MongoLight document:

#string ids which are valid BsonIds will automatically get converted
User.find(selector, options)
User.update(selector, new_document, options)

In addition to any options which the ruby driver supports, the find method can be passed `{:raw => true} which'll cause a hash to be returned rather than a mapped object.

Instances can be saved via save or save! (safe mode).

New instances can be created by passing a hash into the constructor:

User.new({:name => 'goku', :password => 'over 9000!!!'})

Finally, you can always access the underlying collection from a class or object (User.collection or user.collection).

Embedded Documents

Embedded documents are supported. First, define an embedded document using include MongoLight::EmbeddedDocument and the same mongo_accessor method:

class Comment
    include MongoLight::EmbeddedDocument
    mongo_accessor({:title => :t, description => :d})

Next, use the following fancy syntax for your root document:

class User
    include MongoLight::Document
    mongo_accessor({:name => :name, password => :pw, :email => :e, :comment => {:field => :c, :class => Comment}})

Again, this'll make comments accessible on your objects, but store it within the c field.

If you want an array of embedded documents, simply specify :array => true:

:comments => {:field => :c, :class => Comment, array => true}})

Please note that aliasing completely fails when querying embedded documents - you need to use the shortened name:

User.find({:name => 'blah', 'c.t' => 'blah2}) #yes, it sucks