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

Mongodb

  • 1.
  • 2.
    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
  • 3.
    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
  • 4.
    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
  • 5.
    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()
  • 6.
    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
  • 7.
    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
  • 8.
    MongoMapper sudo gem installmongomapper config.gem 'jnunemaker-mongomapper' #rails dependency 'jnunemaker-mongomapper' #merb
  • 9.
    Model class Book include MongoMapper::Document key :title, String key :description, String end
  • 10.
    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 ...
  • 11.
    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
  • 12.
    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
  • 13.
    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
  • 14.
    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
  • 15.
    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
  • 16.
    Embedded Docs cont. classReviews < 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
  • 17.
    Additional info • created_atand 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
  • 18.
    Conclusion Mongodb is agreat 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