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/mongodbosx-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/mongodblinux-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-linuxx86_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++)
drivers bson, document, schema-free Dynamic queries, indexing gridfs (needs an apache/nginx module) RAM Good at the web, faster development time Update in place (good for high update rates) master-master 50s kid

Couchdb (Erlang)
REST json, document, schema-free map/reduce attachments http cache Good at the web, slower development time MVCC (fault tolerant, but requires compacting) replication indy kid

*http://www.mongodb.org/display/DOCS/Comparing+Mongo+DB+and+Couch+DB

Mongodb orms
Ruby mongo-ruby-driver
sudo gem install mongodb-mongo sudo gem install mongodb-mongo_ext (c extension)

Python mongo-python-driver
easy_install pymongo (c extension autoinstalled)

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

autumn
http://autumn-orm.org/

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

mongo-mapper
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
like in couchrest.

MongoMapper like it can in Couchrest

• cannot currently do @doc[‘custom_field’] • 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

Sign up to vote on this title
UsefulNot useful