open-source, high-performance, schema-free, document-oriented database
RDBMS • Great for many applications • Shortcomings • Scalability • Availability • Flexibility
Key-value stores
CouchDB
JSON-style documents
Schema-free • Loosening constraints - added flexibility • Dynamically typed languages (like Ruby!) • Migrations
Dynamic queries • Administration • Ease of development • Familiarity
Focus on performance
Replication
Auto-sharding
Many supported platforms / languages
Good at • The web • Caching • High volume data • Scalability
Less good at • Highly transactional • Ad-hoc business intelligence • Problems that require SQL
MongoDB Basics
Document • Unit of storage (think row) • BSON (Binary JSON) • Represented as a Hash
Collection • Schema-free equivalent of a table • Logical groups of documents • Indexes are per-collection
_id • Special key • Present in all documents • Unique across a Collection • Any type you want
Blog back-end
Post {:author => "mike", :date => Time.new, :text => "my blog post", :tags => ["mongodb", "ruby", "rer09"]}
Comment {:author => “eliot”, :date => Time.new, :text => “great post!”}
New post post = {:author => "mike", :date => Time.new, :text => "my blog post", :tags => ["mongodb", "ruby", "rer09"]} db[“posts”].save(post)
Embedding a comment c = {:author => “eliot”, :date => Time.new, :text => “great post!”} db[“posts”].update({:_id => post[:_id]}, {:$push => {:comments => c}})
Posts by author db[“posts”].find(:author => “mike”)
Last 10 posts db[“posts”].find .sort([[:date, :desc]]) .limit(10)
Posts in the last week last_week = Time.utc(2009, 10, 24) db[“posts”].find(:date => {:$gt => last_week})
Posts ending with ‘RER’ db[“posts”].find(:text => /RER$/)
Posts with a tag db[“posts”].find(:tags => “mongodb”) ... and fast db[“posts”].create_index(“tags”)
Counting posts db[“posts”].count db[“posts”].find(:author => “mike”).count
Basic paging page = 2 page_size = 15 db[“posts”].find.limit(page_size) .skip(page * page_size)
Migration: adding titles • Easy - just start adding them: post = {:author => “mike”, :date => Time.new, :text => “another blog post”, :tags => [“rer09”], :title => “Review from RER 2009”} post_id = db[“posts”].save(post)
Advanced queries • $gt, $lt, $gte, $lte, $ne, $all, $in, $nin • $where db[“posts”].find :$where => “this.author == ‘mike’ || this.title == ‘hello’”})
MongoMapper, Mongoid, MongoRecord, etc.
MongoMapper class User include MongoMapper::Document many :posts end class Post include MongoMapper::Document key :user_id, String key :title, String end user = User.create user.posts.create(:title => 'Foo') # would return post we just created user.posts.find_by_title('Foo')
Other cool stuff • Aggregation and map reduce • Capped collections • Unique indexes • Mongo shell • GridFS
Sharding
Terminology • Shard key • Chunk • Range of the value space • (collection, key, min_val, max_val) • Shard • Single node (or replica pair) • Responsible for set of chunks
• Download MongoDB http://www.mongodb.org • Try it out • Let us know what you think!
• http://www.mongodb.org • irc.freenode.net#mongodb • mongodb-user on google groups • @mongodb, @mdirolf • mike@10gen.com • http://www.slideshare.net/mdirolf

MongoDB at RubyEnRails 2009

Editor's Notes

  • #38 Order Preserving Partitioning Split Migrate
  • #39 Process Diagram Global vs Targeted Operations Config Servers Use Two Phase Commit
  • #40 Server Layout
  • #41 blog post twitter