This document provides information about using MongoDB with Ruby. It discusses installing MongoDB on Mac OS X and Linux, running MongoDB, comparing MongoDB and CouchDB, using MongoDB ORMs like MongoMapper in Ruby applications, defining models and relationships, and additional features of MongoDB and MongoMapper. The conclusion recommends considering MongoDB as an alternative to MySQL for some web applications due to its speed, features, and schema-less flexibility.
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
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.
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
17. 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
18. 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