Simple MongoDB design for Rails apps

5,525 views

Published on

Introduction to MongoDB, Rails Mongoid ORM and some data modelling examples.

Published in: Technology
  • Be the first to comment

Simple MongoDB design for Rails apps

  1. 1. Simple MongoDB design for Web (Rails) apps Sérgio Santos @sdsantos Improve Coimbra
  2. 2. Introduction / Disclamer
  3. 3. Bundlr MongoDB stats MongoDB from the start ~ 3½ years of development ~ 6 GB of data ~ 6 million documents Cloud hosted on MongoHQ
  4. 4. Burocracia MongoDB stats ~ 3 weekends of development ~ 300MB of data ~ 721 documents ~ 400KB per document Cloud hosted on MongoLab
  5. 5. Why MongoDB?
  6. 6. MongoDB 101
  7. 7. Documents
  8. 8. Collections
  9. 9. References
  10. 10. Embeds
  11. 11. Rails MongoDB ORMs
  12. 12. Mongoid vs MongoMapper
  13. 13. Mongoid
  14. 14. Models class Person include Mongoid::Document end person = Person.new person[:name] = 'Sérgio' person[:age] = 26 person.save
  15. 15. Models class Person include Mongoid::Document field :name, type: String field :age, type: Integer end person = Person.new person.name = 'Sérgio' person.age = 26 person.save
  16. 16. Persistence person = Person.create(name: 'Sérgio', age: 26) person.update_attributes(name: 'Sérgio Santos') person.touch person.delete person.destroy person.rename(:name, :first_name)
  17. 17. Querying person = Person.find("4baa56f1230048567300485c") people = Person.where(age: 18) people = Person.where(name: 'Sérgio').not(age: 26) Person.count Person.all.avg(:age) -- INSERT MAP/REDUCE CLEVER EXAMPLE HERE --
  18. 18. References class Band include Mongoid::Document has_many :members end class Member include Mongoid::Document field :name, type: String belongs_to :band end
  19. 19. References # The parent band document. { "_id" : ObjectId("4d3ed089fb60ab534684b7e9") } # The child member document. { "_id" : ObjectId("4d3ed089fb60ab534684b7f1"), "name" : "Matt Berninger" "band_id" : ObjectId("4d3ed089fb60ab534684b7e9") }
  20. 20. Embeds class Band include Mongoid::Document embeds_many :albums end class Album include Mongoid::Document field :name, type: String embedded_in :band end
  21. 21. Embeds { "_id" : ObjectId("4d3ed089fb60ab534684b7e9"), "albums" : [ { "_id" : ObjectId("4d3ed089fb60ab534684b7e0"), "name" : "Boxer", } ] }
  22. 22. Extras timestamps identity map & cache paranoia versioning
  23. 23. Cloud Hosting
  24. 24. The Nice Stuff
  25. 25. No need to create the collection class Band include Mongoid::Document end
  26. 26. Store anything class ParamsStore include Mongoid::Document end class ApplicationController < ActionController::Base before_filter do Stuff.create(params) end end
  27. 27. Store long stuff class Website include Mongoid::Document field :html, type: String field :css, type: String field :javascript, type: String embeds_many :images end class Image include Mongoid::Document field :size, type: Integer field :file, type: Moped::BSON::Binary embedded_in :website end
  28. 28. Geo class Person include Mongoid::Document field :location, :type => Array index( { location: Mongo::GEO2D }, { min: -180, max: 180 } ) end coimbra_location = [20, -8] Person.geo_near(coimbra_location).spherical
  29. 29. Full text search class Document include Mongoid::Document field :content, :type => String index( {:content => 'text'}, {:default_language => 'portuguese’} ) end Document.text_search('IKEA')
  30. 30. Caveats (not so nice) No joins Impact of key length No integrity checks for references Document size limit of 16MB Nesting depth limit of 100
  31. 31. ( Bundlr ) Examples
  32. 32. Settings class User include Mongoid::Document embeds_one :settings end class Settings include Mongoid:Document field :receive_emails, type: Boolean field :theme, type: Symbol embedded_in :user end
  33. 33. Oauths class User include Mongoid::Document embeds_many :oauths index [["oauths.provider", Mongo::ASCENDING], ["oauths.uid", Mongo::ASCENDING]] end class Oauth include Mongoid:Document field :provider, type: String field :token, type: String field :secret, type: String field :uid, type: String embedded_in :user end
  34. 34. Activity Stream class Activity include Mongoid::Document include Mongoid::Timestamps field :verb, :type => Symbol field :actor, :type => Hash field :object, :type => Hash field :target, :type => Hash field :receivers, :type => Array embeds_many :likes end
  35. 35. Relationships class User include Mongoid::Document has_and_belongs_to_many :followers, :class_name => "User", :inverse_of => :followed_users end { _id: ObjectId("4d541f6823380f670d000008"), follower_ids: [ ObjectId("4d4ea8ec86d56d2907000003"), ObjectId("50fe17c226c1b7000200018a") ], } Need smarter relationships? Embed them!
  36. 36. Other examples Model hierarchy Migrations Changing schema? No right way of doing things… is all about context!
  37. 37. Wrapping up…
  38. 38. Sérgio Santos @sdsantos me@sergiosantos.info Simple MongoDB design for Web (Rails) apps Improve Coimbra

×