Corporate Blog

Ruby and NoSQL

A new store and handle data approach has recently gained its popularity among scalable web applications. Use of any major NoSQL database has several benefits in comparison to usual RDBMS:
  • a) Faster to append new data
  • b) Simple to store key-value pairs
  • c) Convenient for use with REST designs

Let’s reflect on how we can use NoSQL with Ruby. In order to do so, we will review the following NoSQL databases: Cassandra, MongoDB and CouchDB. Ruby supports each one of them over corresponding gems. In this blog post we will be using Ruby 1.8.7 with Rails 3.0 under Ubuntu 9.10 OS.

Cassandra

Cassandra is a highly scalable, eventually consistent, distributed and structured key-value store. It brings together the distributed system technologies from Dynamo, and the data model from Google’s BigTable. Like Dynamo, Cassandra is eventually consistent. It also provides a ColumnFamily-based data model richer than typical key/value systems just like the Google’s BigTable

Cassandra is great for situations that require the following:

  • fast read or write performance
  • the ability to add more machines as you need additional capacity
  • reliable cross-datacenter replication

Installation:

Download from http://cassandra.apache.org/
Latest version (on blog moment) – 0.6.5
Copy to home folder and unzip it:


tar -zxvf apache-cassandra-0.6.5.tar.gz
cd apache-cassandra-0.6.5

Create folder for log files and provide necessary permission to them:


sudo mkdir -p /var/log/cassandra
sudo chown -R `whoami` /var/log/cassandra
sudo mkdir -p /var/lib/cassandra
sudo chown -R `whoami` /var/lib/cassandra

Start Cassandra:


bin/cassandra -f

Make sure it started by using command line client:


bin/cassandra-cli --host localhost --port 9160

Install Ruby gem for Cassandra:


sudo gem install cassandra

Create simple program:

require 'rubygems'
require 'cassandra'

# create sample Keyspace1 object
store = Cassandra.new('Keyspace1');

# insert few things
store.insert(:Standard2, 'jsmith', { 'first' => 'John'});
store.insert(:Standard2, 'jsmith', { 'last' => 'Smith'});
store.insert(:Standard2, 'jsmith', { 'age' => '42'});

# query information
user = store.get(:Standard2, 'jsmith')

# show result
user.each do |field|
  puts field.inspect
end

# remove entries
store.remove(:Standard2, 'jsmith')

Output of the program above:

["age", "42"]
["first", "John"]
["last", "Smith"]

MongoDB

MongoDB bridges the gap between key-value stores (which are fast and highly scalable) and traditional RDBMS systems (which provide rich queries and deep functionality).

MongoDB (from “humongous”) is a scalable, high-performance, open source, document-oriented database. MongoDB can be selected for the following reasons:

Installation:

Download from http://www.mongodb.org/
Latest version (on blog moment) – 1.6.3
Copy to home folder and unzip it:


tar -zxvf mongodb-linux-i686-1.6.3.tgz
cd mongodb-linux-i686-1.6.3

Create database folder:


mkdir db/data

Start mongo:


bin/mongod run -dbpath ./db/data

Install Ruby gem for mongodb:


sudo gem install mongo

Install bson gem (required by driver) and C extension for them (for performance boost):


sudo gem install bson
sudo gem install bson_ext

Create simple program:

require 'rubygems'
require 'mongo'

# open a connection
db = Mongo::Connection.new('localhost').db("mydb")

# obtain a collection (it will be created if not exists)
coll = db.collection('test')

# prepare and insert document into collection
doc = { 'name' => 'MongoDB', 'type' => 'database', 'count' => '1',
        'auth' => { 'login' => 'test', 'password' => 'mongo' }}
coll.insert(doc)

# update document
doc['auth']['login'] = 'john'
coll.save(doc)

# query document
coll.find('name' => 'MongoDB').each do |row|
  puts row.inspect
end

# remove document
coll.remove( { 'name' => 'MongoDB'} )
puts coll.count()

Output of the program above:

	{"_id"=>BSON::ObjectId('4cc6b622dc346c17bc000001'), "name"=>"MongoDB", 	"auth"=>{"password"=>"mongo", "login"=>"john"}, "count"=>"1", "type"=>"database"}
	0

CouchDB

A CouchDB server hosts named databases, which stores documents. Each document is uniquely named in the database, and CouchDB provides a RESTful HTTP API for reading and updating (add, edit, delete) database documents.

Documents are the primary unit of data in CouchDB and consist of any number of fields and attachments. Documents also include metadata that’s maintained by the database system. Document fields are uniquely named and contain values of varying types (text, number, boolean, lists, etc), and there is no set limit to text size or element count.
User can just chuck arbitrary JSON objects up at this thing and it’ll store it. No setup, no schemas, no nothing.

Installation:
Download from http://couchdb.apache.org
Latest version (on blog moment) – 1.0.1
Copy to home folder and unzip it
Install all dependencies required to build couchdb from sources:


sudo apt-get build-dep couchdb
sudo apt-get install libmozjs-dev
sudo apt-get install curl

Configure and make:


sudo ./configure --prefix=/usr/local/ --with-js-lib=/usr/lib/xulrunner-devel-1.9.2.10/lib --with-js-include=/usr/lib/xulrunner-devel-1.9.2.10/include
sudo make
sudo make install

Change home directory to:


/usr/local/var/lib/couchdb/

Change file ownership from root to couchdb user and adjust permissions:


chown -R couchdb: /usr/local/var/lib/couchdb
chown -R couchdb: /usr/local/var/log/couchdb
chown -R couchdb: /usr/local/var/run/couchdb
chown -R couchdb: /usr/local/etc/couchdb
chmod 0770 /usr/local/var/lib/couchdb/
chmod 0770 /usr/local/var/log/couchdb/
chmod 0770 /usr/local/var/run/couchdb/
chmod 664 /usr/local/etc/couchdb/*.ini
chmod 775 /usr/local/etc/couchdb/*.d

Start couchdb, use ‘couchdb’ as a password when asked


cd /etc/init.d
ln -s /usr/local/etc/init.d/couchdb couchdb
sudo /etc/init.d/couchdb start

Verify couchdb is running:


curl http://127.0.0.1:5984/

If installation is successful then you should see

	{"couchdb":"Welcome","version":"1.0.1"}

Install couchrest Ruby gem for couchdb:


sudo gem install couchrest

Create simple program

require 'rubygems'
require 'couchrest'

# open a connection
db = CouchRest.database!('http://localhost:5984/mydb')

# prepare a document
doc = { 'name' => 'CouchDB', 'type' => 'database', 'count' => '1',
        'auth' => { 'login' => 'test', 'password' => 'couch' }}

# save it in the database
res = db.save_doc(doc)

# query document
db.documents(:name => 'CouchDB')

# delete document
doc = db.get(res['id'])
doc.destroy

Sphere Consulting, Inc. – Global company that provides custom Ruby on Rails web application development services. Company’s team is comprised of Ruby on Rails experts with proven experience in development and deployment of various Ruby on Rails web applications for large scale businesses and start-ups in different industries.

Comments

  1. pocheptsov says:

    Interesting examples of using NoSql or if to be more accurate start points, I will look for continue series, it’s interesting.

  2. Robert Reiz says:

    Hey man. Thanks for this article. I am working with MongoDB and Ruby on Rails since a while. I am using the MongoID wrapper to access my mongo database. It is very convenient. Check out the project here: http://mongoid.org/. Here is a Quickstart Tutorial: http://robert-reiz.com/2012/03/05/rails-mongodb-tutorial/

    I would like to learn more about Cassandra. Does anybody know a good wrapper for Cassandra. Something what is similar to ActiveRecord or MongoID? That would be awesome. THX.

Trackbacks

  1. ehcache.net says:

    Ruby and NoSQL…

    new store and handle data approach has recently gained its popularity among scalable web applications. Use of any major NoSQL database has several benefits in comparison to usual RDBMS: a) Faster to append new data b) Simple to store key-value pairs c)…

Speak Your Mind

*

CAPTCHA
Change the CAPTCHA codeSpeak the CAPTCHA code