You are on page 1of 18

MongoDB

Getting started, Couch, and MongoMapper


Who am I?
• Scott Motte / 25 / Perris, CA
• mid-level rubyist that prefers merb
• spitfiresky.com
• twitter.com/spitfiresky
• github.com/scottmotte
• scott@spitfiresky.com
Leopard Install (0.9.7)

• mkdir -p /data/db

• wget http://downloads.mongodb.org/osx/mongodb-
osx-i386-0.9.7.tgz

• sudo tar xvzf mongodb-osx-i386-0.9.7.tgz -C /usr/local

• sudo cp -R /usr/local/mongodb-osx-i386-0.9.7/bin/ /usr/


local/bin
Linux Install (0.9.7)
• mkdir -p /data/db

• wget http://downloads.mongodb.org/linux/mongodb-
linux-x86_64-0.9.6.tgz

• sudo tar -zxvf mongodb-linux-x86_64-0.9.7.tgz -C /usr/


local

• sudo chmod 755 -R /usr/local/mongodb-linux-


x86_64-0.9.7

• sudo cp -R /usr/local/mongodb-linux-x86_64-0.9.7/bin/* /
usr/local/bin
Running it

• sudo mongod run &

• mongo (mysql-like command line)

• use bookstore_development

• db.books.save({ title: "Ender's Game", description:


'zero gravity and mind games' })

• db.books.findOne()
Mongo or Couch
Mongodb (C++) Couchdb (Erlang)
drivers REST

bson, document, schema-free json, document, schema-free

Dynamic queries, indexing map/reduce


gridfs
attachments
(needs an apache/nginx module)
RAM http cache
Good at the web, faster Good at the web, slower
development time development time
Update in place (good for high MVCC (fault tolerant, but requires
update rates) compacting)
master-master replication

50s kid indy kid


*http://www.mongodb.org/display/DOCS/Comparing+Mongo+DB+and+Couch+DB
Mongodb orms
Ruby Python
mongo-ruby-driver mongo-python-driver
sudo gem install mongodb-mongo
easy_install pymongo (c extension auto-
sudo gem install mongodb-mongo_ext (c
installed)
extension)

active-record-adapter autumn
http://github.com/-mongodb/activerecord-mongo-adapter http://autumn-orm.org/

mongorecord mongo-mapper
http://github.com/mongodb/mongo-activerecord-ruby http://github.com/jeffjenkins/mongo-mapper

mongomapper
http://github.com/jnunemaker/mongomapper
MongoMapper

sudo gem install mongomapper

config.gem 'jnunemaker-mongomapper' #rails

dependency 'jnunemaker-mongomapper' #merb


Model

class Book
include MongoMapper::Document
key :title, String
key :description, String
end
Controller
class Books < Application
def index
@books = Book.all
display @books
end

def show(id)
@book = Book.find(id)
raise NotFound unless @book
display @book
end
...
Validations
class Book
include MongoMapper::Document
key :title, String
key :description, String

validates_presence_of :title
#validates_numericality_of
#validates_length_of
#validates_format_of
#more
end

*http://github.com/jnunemaker/validatable
Callbacks
class Book
..
key :description, String

before_save :append_signature
def append_signature
self.description << " ~Corner Bookstore"
end

#after_save
#before_validation
end

*http://api.rubyonrails.org/classes/ActiveSupport/Callbacks.html
Relationships
class Book
include MongoMapper::Document
key :title, String
key :description, String
has_many :reviews
end

class Review
include MongoMapper::Document
key :author, String
key :review, String
belongs_to :book
end
Relationships cont.
Finding
@book = Book.first
@reviews = @book.reviews

Displaying
@reviews.each do |review|
review.author
end
@reviews[0] # return first review

Be careful
@user.tweets.size #slow
Tweet.count(:user_id => @user.id) #fast
Embedded Documents
class Review
include MongoMapper::EmbeddedDocument

key :uuid, String, :default => XGen::Mongo::Driver::ObjectID.new


key :author, String
key :review, String
key :created_at, Time, :default => Time.now.utc

before_validation do
self.uuid = XGen::Mongo::Driver::ObjectID.new
end
end

*http://groups.google.com/group/mongomapper/browse_thread/thread/178b8c5105ebedd8
Embedded Docs cont.
class Reviews < Application
..
def create(review)
@flight = Flight.find(params['flight_id'])
@review = Review.new(review)
if @review.valid? && @flight.reviews << @review && @flight.save
redirect '/wherever’' :message => {:notice => "Review made"}
else
message[:error] = "Review fail"
render :new
end
end
end
# in router.rb
resources :flights, :identify => :id do
resources :reviews, :identify => :uuid
end # /flights/:flight_id/comments/new
Additional info
• created_at and updated_at are included
automatically by MongoMapper
• _id cannot currently be set with
MongoMapper like it can in Couchrest
• cannot currently do @doc[‘custom_field’]
like in couchrest.
• indexing: @doc.ensure_index :login
Conclusion
Mongodb is a great trade off
of speed, features, and
schema-less freedom, and it
now has its developer friendly
orm - mongomapper.

Strongly consider using it in a


web app you otherwise by
default would use mysql.

Then put together your


models and use script/server
or bin/merb -i to test your
performance improvements.

~ Scott Motte