Rails + MongoDB Tutorial. Quickstart.

This is a Quickstart Tutorial for Rails + MongoDB. Ruby on Rails and MongoDB, a document based database, is a pretty good fit. It is very easy to integrate MongoDB with Rails. If you want to know how to install MongoDB, check out this article here: Installing MongoDB on Mac OS X Lion. Or this here: Installing MongoDB on Linux.

I assume you are familiar with Ruby on Rails 🙂

There are several GEMs to interact with MongoDB. I used the MongoID GEM. That worked pretty good for me. Just add this to your Gemfile:

gem 'bson_ext', '1.6.0'  
gem 'mongo', '1.6.0'
gem 'mongoid', '2.4.6'

And run “bundle install” on your project, to load the GEM from the internet. And add the file mongoid.yml to your config folder:

development:
    host: localhost
    database: myapp_dev

test:
    host: localhost
    database: myapp_test

production:
    host: localhost
    database: myapp_prod

This is the file where you are configuring the access to the database. If your mongodb instance is running locale you don’t need any username or password settings. Now you have to load the mongoid.yml file. You can do that by adding this line to your application.rb inside of the “class Application”.

Mongoid.load!("config/mongoid.yml")

Than just add a new Model to your project. For example “User”. That could look like that:

class User
include Mongoid::Document
include Mongoid::Timestamps
field :username, type: String
field :firstname, type: String
field :llastname, type: String
field :email, type: String
filed :age, type: Integer

end

That’s it. You just have to include the Mongoid:Document.

include Mongoid::Document

And define your fields! Now you can create a new user and save it like that:

user = User.new
user.username = "mike"
user.firstname = "Mike"
user.lastname = "Boby"
user.age = 44
user.save

Or make a query like that:

user = User.where( username: "mike")

Check out the Criteria API for MongoID. That is pretty straight forward. Worked pretty well for me.

MongoDB. Growing local.X files

I have a ReplicaSet with MongoDB 2.0.2 on two Debian Linux 6.0 servers. The ReplicaSet is working fine. But on one of the servers I realized that there are a bunch of local.x files.

  • local.0
  • local.1
  • local.22.

Each of them 2.1 GB. The actual database/collections are less than 1 GB. I am just wondering why there are all this files and taking more than 40 GB space ??

On a dedicated server with 800 GB this is not a big deal, but on a small VServer with 60GB HD this could be a huge problem!

If somebody have the same problem and an solution for it, please let me know!

mongodb replicasets with read errors

If you have a ReplicaSet setup with MongoDB and you try to read from a slave node and you get this Exception here:

mongdodb, replicates and error: { “$err” : “not master and slaveok=false”, “code” : 13435 }

or this here:

uncaught exception: count failed: { "errmsg" : "not master", "ok" : 0 }

Than the problem is that you are not allowed to read from the slave. By default MongoDB disables reads from Slaves. You can solve that by executing this here on the slave in the mongo shell:

rs.slaveOk()

Or just reconfigure your mongo driver.

MongoDB Import / Export

If you want to export a whole database on MongoDB, this is the tool you are looking for:

mongodump --host <HOST> --port <PORT> --db <DATABASE> --username <USERNAME> --password <PASSWORD>

that will export all your collections into a separate folder. Each collection is exported to a single bson file. After you executed the command you will have a “dump” folder. Under the dump folder there is folder the the name of the DATABASE and under the database folder are the collections on separate bson files.

If you want to import the files into another MongoDB on another server, this is the tool you are looking for:

mongorestore --host <HOST> --port <PORT> --username <USERNAME> --port <PORT> dump/<DATABASENAME>

That worked for me fine 🙂

 

MongoDB Indexing

I am using Ruby and MongoDB in a project and I got today this Exception here:

Mongo::OperationFailure (too much data for sort() with no index):

The Problem was really that the searched field was not indexed. You can add an index like this:

db.products.ensureIndex({name:1});

That means the attribute “name” on the “products” document get indexed in asc order. That improved my search results enorm. But if the search results are to big, you will still get the same error.

I just solved the problem by limiting the search results. If you are using MongoID for ruby you can add this to your query:

.limit(300)

That means you will just get the first 300 search results. In my case that is perfect.

Useful MongoDB commands

How to install MongoDB on Mac OS X I showed already here:
https://robert-reiz.com/2011/08/11/installing-mongodb-on-mac-ox-x-lion/

If everything is installed correctly, you can start the server process as root with this command:

mongod

and the client as no root with this command:

mongo

By default you are logged in into the “test” database. You can show all dbs with this command:

show dbs

you can switch to an existing DB or create a new DB with this command:

use mynewdb

With this command here you can show alle “collections” inside of the DB:

show collections

You can make an insert with this command:

db.users.save( { name : "myname" } )

If the collections “users” does not exist it will be created with the first call. With this command you can see all entries in the collection “users”:

db.users.find()

With count() you can see how many elements are in the collection.

db.users.count()

And with “remove” you can remove alle elements from a collections.

db.users.remove()

And with drop you can drop the entire collection.

db.users.drop()

Installing MongoDB on Mac OX X Lion

Today I tried to install mongodb via MacPorts on Mac OS X Lion. I got this error message:

Error: Target org.macports.build returned: shell command failed (see log for details)
Log for mongodb is at: /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_ports_databases_mongodb/mongodb/main.log
Error: Status 1 encountered during processing.
To report a bug, see <http://guide.macports.org/#project.tickets>

Maybe it is not the best idea to install MongoDB via MacPorts. I just downloaded the compiled binarys from the MongoDB Homepage: http://www.mongodb.org/downloads. Just unzip it and that’s it.

No you have to create a directory.

mkdir /data
cd /data
mkdir db

MongoDB expects that this directory exists and puts all necessary DB files into this directory.

Navigate in the command line to the unpacked directory and execute this command as root to start the MongoDB server:

./bin/mongod

And the server is running 🙂
In another shell you can start the client. The client can run without root rights.

./bin/mongo

Now you can start to work

> db.foo.save( { a : 1 } )
> db.foo.find()