- 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:
- Very easy to install
- Very easy replication, including master-master support. In testing, this caught up with our live DB very quickly and stayed in sync without difficulty
- Automated sharding being developed
- Good documentation
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.
Interesting examples of using NoSql or if to be more accurate start points, I will look for continue series, it’s interesting.
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.