shutl mongob usergroup talk jan 2013
DESCRIPTION
Introduction into MongoDB and Ruby at the January 2013 MongoDB user group, LondonTRANSCRIPT
MongoDB and Ruby
domain modeling with MongoMapper
Wednesday, 23 January 13
Volker Pacher
senior developer @shutl
@vpacher
http://github.com/vpacher
Wednesday, 23 January 13
Wednesday, 23 January 13
Wednesday, 23 January 13
• SaaS platform
Wednesday, 23 January 13
• SaaS platform
• we provide an API for carriers and merchants
Wednesday, 23 January 13
• SaaS platform
• we provide an API for carriers and merchants
• customers can chose between a delivery either:
Wednesday, 23 January 13
• SaaS platform
• we provide an API for carriers and merchants
• customers can chose between a delivery either: within 90 minutes of purchase
Wednesday, 23 January 13
• SaaS platform
• we provide an API for carriers and merchants
• customers can chose between a delivery either: within 90 minutes of purchase or a 1 hour window of their choice
Wednesday, 23 January 13
• SaaS platform
• we provide an API for carriers and merchants
• customers can chose between a delivery either: within 90 minutes of purchase or a 1 hour window of their choice (same day or any day)
Wednesday, 23 January 13
• SaaS platform
• we provide an API for carriers and merchants
• customers can chose between a delivery either: within 90 minutes of purchase or a 1 hour window of their choice (same day or any day)
• fastest delivery to date 14:00 min
Wednesday, 23 January 13
• SaaS platform
• we provide an API for carriers and merchants
• customers can chose between a delivery either: within 90 minutes of purchase or a 1 hour window of their choice (same day or any day)
• fastest delivery to date 14:00 min
• customers: Argos, Maplins, DrEd.com ...
Wednesday, 23 January 13
• SaaS platform
• we provide an API for carriers and merchants
• customers can chose between a delivery either: within 90 minutes of purchase or a 1 hour window of their choice (same day or any day)
• fastest delivery to date 14:00 min
• customers: Argos, Maplins, DrEd.com ...
• json api
Wednesday, 23 January 13
• SaaS platform
• we provide an API for carriers and merchants
• customers can chose between a delivery either: within 90 minutes of purchase or a 1 hour window of their choice (same day or any day)
• fastest delivery to date 14:00 min
• customers: Argos, Maplins, DrEd.com ...
• json api
•built with sinatra, jruby, neo4j and mongodb
Wednesday, 23 January 13
Wednesday, 23 January 13
5 Branding Guidelines
Logo Colours
The primary logo below contains the full title – Shutl. Wherever possible the rocket
should be present on the logo in Shutl Red as shown. It can also appear in black
where budget is a restraint.
Black on white Reverse (white) on darker tones
red on white red on lighter tones
Shutl Main Red:
Pantone 485 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Black:
Pantone BLACK
C0 M0 Y0 K0100
Please note:
The black logo should never
appear on in any ‘dark’ colour
background.
Shutl Accent Red:
Pantone 484 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Accent Grey:
Pantone BLACK
C0 M0 Y0 K70
@ 70%
Shutl Colour Palette:
Let’s get going:
Wednesday, 23 January 13
5 Branding Guidelines
Logo Colours
The primary logo below contains the full title – Shutl. Wherever possible the rocket
should be present on the logo in Shutl Red as shown. It can also appear in black
where budget is a restraint.
Black on white Reverse (white) on darker tones
red on white red on lighter tones
Shutl Main Red:
Pantone 485 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Black:
Pantone BLACK
C0 M0 Y0 K0100
Please note:
The black logo should never
appear on in any ‘dark’ colour
background.
Shutl Accent Red:
Pantone 484 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Accent Grey:
Pantone BLACK
C0 M0 Y0 K70
@ 70%
Shutl Colour Palette:
• install mongodb with brew install mongodb
Let’s get going:
Wednesday, 23 January 13
5 Branding Guidelines
Logo Colours
The primary logo below contains the full title – Shutl. Wherever possible the rocket
should be present on the logo in Shutl Red as shown. It can also appear in black
where budget is a restraint.
Black on white Reverse (white) on darker tones
red on white red on lighter tones
Shutl Main Red:
Pantone 485 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Black:
Pantone BLACK
C0 M0 Y0 K0100
Please note:
The black logo should never
appear on in any ‘dark’ colour
background.
Shutl Accent Red:
Pantone 484 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Accent Grey:
Pantone BLACK
C0 M0 Y0 K70
@ 70%
Shutl Colour Palette:
• install mongodb with brew install mongodb
• in your gemfile:
Let’s get going:
Wednesday, 23 January 13
5 Branding Guidelines
Logo Colours
The primary logo below contains the full title – Shutl. Wherever possible the rocket
should be present on the logo in Shutl Red as shown. It can also appear in black
where budget is a restraint.
Black on white Reverse (white) on darker tones
red on white red on lighter tones
Shutl Main Red:
Pantone 485 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Black:
Pantone BLACK
C0 M0 Y0 K0100
Please note:
The black logo should never
appear on in any ‘dark’ colour
background.
Shutl Accent Red:
Pantone 484 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Accent Grey:
Pantone BLACK
C0 M0 Y0 K70
@ 70%
Shutl Colour Palette:
• install mongodb with brew install mongodb
• in your gemfile:
• gem ‘mongo’
Let’s get going:
Wednesday, 23 January 13
5 Branding Guidelines
Logo Colours
The primary logo below contains the full title – Shutl. Wherever possible the rocket
should be present on the logo in Shutl Red as shown. It can also appear in black
where budget is a restraint.
Black on white Reverse (white) on darker tones
red on white red on lighter tones
Shutl Main Red:
Pantone 485 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Black:
Pantone BLACK
C0 M0 Y0 K0100
Please note:
The black logo should never
appear on in any ‘dark’ colour
background.
Shutl Accent Red:
Pantone 484 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Accent Grey:
Pantone BLACK
C0 M0 Y0 K70
@ 70%
Shutl Colour Palette:
• install mongodb with brew install mongodb
• in your gemfile:
• gem ‘mongo’
• gem ‘bson’
Let’s get going:
Wednesday, 23 January 13
5 Branding Guidelines
Logo Colours
The primary logo below contains the full title – Shutl. Wherever possible the rocket
should be present on the logo in Shutl Red as shown. It can also appear in black
where budget is a restraint.
Black on white Reverse (white) on darker tones
red on white red on lighter tones
Shutl Main Red:
Pantone 485 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Black:
Pantone BLACK
C0 M0 Y0 K0100
Please note:
The black logo should never
appear on in any ‘dark’ colour
background.
Shutl Accent Red:
Pantone 484 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Accent Grey:
Pantone BLACK
C0 M0 Y0 K70
@ 70%
Shutl Colour Palette:
• install mongodb with brew install mongodb
• in your gemfile:
• gem ‘mongo’
• gem ‘bson’
• gem ‘bson_ext’
Let’s get going:
Wednesday, 23 January 13
5 Branding Guidelines
Logo Colours
The primary logo below contains the full title – Shutl. Wherever possible the rocket
should be present on the logo in Shutl Red as shown. It can also appear in black
where budget is a restraint.
Black on white Reverse (white) on darker tones
red on white red on lighter tones
Shutl Main Red:
Pantone 485 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Black:
Pantone BLACK
C0 M0 Y0 K0100
Please note:
The black logo should never
appear on in any ‘dark’ colour
background.
Shutl Accent Red:
Pantone 484 C
C0 M100 Y99 K4
R208 G31 B40
HEX D01F28
Shutl Accent Grey:
Pantone BLACK
C0 M0 Y0 K70
@ 70%
Shutl Colour Palette:
• install mongodb with brew install mongodb
• in your gemfile:
• gem ‘mongo’
• gem ‘bson’
• gem ‘bson_ext’
• run bundle install
Let’s get going:
Wednesday, 23 January 13
MongoMapper
Wednesday, 23 January 13
MongoMapper
• http://mongomapper.com/
Wednesday, 23 January 13
MongoMapper
• http://mongomapper.com/
• written by John Nunemaker (github)
Wednesday, 23 January 13
MongoMapper
• http://mongomapper.com/
• written by John Nunemaker (github)
• code at https://github.com/jnunemaker/
mongomapper
Wednesday, 23 January 13
Alternatives:
Wednesday, 23 January 13
Alternatives:
• Mongoid: http://mongoid.org/en/mongoid/index.html
Wednesday, 23 January 13
Alternatives:
• Mongoid: http://mongoid.org/en/mongoid/index.html
• MongoODM: https://github.com/carlosparamio/mongo_odm
Wednesday, 23 January 13
Alternatives:
• Mongoid: http://mongoid.org/en/mongoid/index.html
• MongoODM: https://github.com/carlosparamio/mongo_odm
• MongoModel: http://www.mongomodel.org/
Wednesday, 23 January 13
installation:
Wednesday, 23 January 13
installation:
• in your gemfile:
Wednesday, 23 January 13
installation:
• in your gemfile:
• gem ‘mongo_mapper’
Wednesday, 23 January 13
installation:
• in your gemfile:
• gem ‘mongo_mapper’
• run bundle install
Wednesday, 23 January 13
include MongoMapper
MongoMapper.connection = Mongo::Connection.new('localhost', 27017)MongoMapper.database = ‘development’
MongoMapper.database.authenticate('username','password')
db initialization:
Wednesday, 23 January 13
class User include MongoMapper::Document
key :name, String, required: true key :age, Integer
one :address many :notes
timestamps!end
First document:
Wednesday, 23 January 13
embedded document:
class Note include MongoMapper::EmbeddedDocument
key :text, Stringend
Wednesday, 23 January 13
create a document:
user = User.new(name:'James Chester')user.notes.build(text:'a note')
user.save!
User.where(:name => 'James Chester').first
Wednesday, 23 January 13
What is an embedded document?
Wednesday, 23 January 13
What is an embedded document?
• a document has it’s own collection in the database (table)
Wednesday, 23 January 13
What is an embedded document?
• a document has it’s own collection in the database (table)
• an embedded document can only reside inside a document
or another embedded document
Wednesday, 23 January 13
What is an embedded document?
• a document has it’s own collection in the database (table)
• an embedded document can only reside inside a document
or another embedded document
• the alternative in sql without join table would be to serialize
Wednesday, 23 January 13
What is an embedded document?
• a document has it’s own collection in the database (table)
• an embedded document can only reside inside a document
or another embedded document
• the alternative in sql without join table would be to serialize
• in MongoDB it is possible to query inside embedded
documents and structures and also to index inside them
Wednesday, 23 January 13
When to use embedded and when not to
Wednesday, 23 January 13
When to use embedded and when not to
• only embed when the document will be shown in the
context of the parent document
Wednesday, 23 January 13
When to use embedded and when not to
• only embed when the document will be shown in the
context of the parent document
• if you need to access to the documents on it’s own use
associations (i.e. all notes)
Wednesday, 23 January 13
When to use embedded and when not to
• only embed when the document will be shown in the
context of the parent document
• if you need to access to the documents on it’s own use
associations (i.e. all notes)
• they work the same way but declare a normal document
instead of an embedded one
Wednesday, 23 January 13
{ id: '50fd8a786bcb608e1c000002',name: 'James Chester',address: {},notes: [ { id: '50fd8b246bcb608e1c000003', text: 'a note'}
]}
Wednesday, 23 January 13
types:
Wednesday, 23 January 13
types:
• mongomapper supports the ruby data types:
Integer, Float, String, Array, Hash, Object, Time, NilClass
Wednesday, 23 January 13
types:
• mongomapper supports the ruby data types:
Integer, Float, String, Array, Hash, Object, Time, NilClass
• additionally mongomapper adds support for:
Binary, Boolean, Date, ObjectId and Set
Wednesday, 23 January 13
types:
• mongomapper supports the ruby data types:
Integer, Float, String, Array, Hash, Object, Time, NilClass
• additionally mongomapper adds support for:
Binary, Boolean, Date, ObjectId and Set
• ability to add custom types
Wednesday, 23 January 13
custom types:
class UpcaseString def self.to_mongo(value) value.nil? ? nil : value.to_s.upcase end
def self.from_mongo(value) to_mongo(value) endend
Wednesday, 23 January 13
finding a document:
Wednesday, 23 January 13
finding a document:
• find by id: User.find(‘50fd8a726bcb608e1c000001’)
Wednesday, 23 January 13
finding a document:
• find by id: User.find(‘50fd8a726bcb608e1c000001’)
• find by field: User.first(:name => 'James')
Wednesday, 23 January 13
finding a document:
• find by id: User.find(‘50fd8a726bcb608e1c000001’)
• find by field: User.first(:name => 'James')
• query inside embedded document or structure (Hash)
User.all(‘address.postcode’ => 'EC2A 4HJ')
Wednesday, 23 January 13
finding a document:
• find by id: User.find(‘50fd8a726bcb608e1c000001’)
• find by field: User.first(:name => 'James')
• query inside embedded document or structure (Hash)
User.all(‘address.postcode’ => 'EC2A 4HJ')
• finders are:
.find, .all, .first, .last, .paginate
Wednesday, 23 January 13
dynamic querying:
Wednesday, 23 January 13
dynamic querying:
• MongoMapper uses plucky to the allow the construction of query
proxy objects that only get executed when needed
Wednesday, 23 January 13
dynamic querying:
• MongoMapper uses plucky to the allow the construction of query
proxy objects that only get executed when needed
• https://github.com/jnunemaker/plucky
Wednesday, 23 January 13
dynamic querying:
• MongoMapper uses plucky to the allow the construction of query
proxy objects that only get executed when needed
• https://github.com/jnunemaker/plucky
• User.where(:created_at.gte => 3.days.ago).sort(:created.desc)
Wednesday, 23 January 13
dynamic querying:
• MongoMapper uses plucky to the allow the construction of query
proxy objects that only get executed when needed
• https://github.com/jnunemaker/plucky
• User.where(:created_at.gte => 3.days.ago).sort(:created.desc)• .where, .count, .field, .sort/.order, .limit,
.skip, .offset
Wednesday, 23 January 13
operators:
Wednesday, 23 January 13
operators:
• all mongodb operators can be used directly in mongomapper
Wednesday, 23 January 13
operators:
• all mongodb operators can be used directly in mongomapper
• http://docs.mongodb.org/manual/reference/operators/
Wednesday, 23 January 13
operators:
• all mongodb operators can be used directly in mongomapper
• http://docs.mongodb.org/manual/reference/operators/
• User.where(:age => {:$gt => 20, :$lt => 45})
Wednesday, 23 January 13
operators:
• all mongodb operators can be used directly in mongomapper
• http://docs.mongodb.org/manual/reference/operators/
• User.where(:age => {:$gt => 20, :$lt => 45})
• or shorthand:
Wednesday, 23 January 13
operators:
• all mongodb operators can be used directly in mongomapper
• http://docs.mongodb.org/manual/reference/operators/
• User.where(:age => {:$gt => 20, :$lt => 45})
• or shorthand:
• User.where(:age.gt => 25)
Wednesday, 23 January 13
destroy/delete:
Wednesday, 23 January 13
destroy/delete:
• destroy triggers callbacks, delete does not
Wednesday, 23 January 13
destroy/delete:
• destroy triggers callbacks, delete does not
• User.destroy(‘50fd8a786bcb608e1c000002’)
Wednesday, 23 January 13
destroy/delete:
• destroy triggers callbacks, delete does not
• User.destroy(‘50fd8a786bcb608e1c000002’)
• User.destroy_all
Wednesday, 23 January 13
destroy/delete:
• destroy triggers callbacks, delete does not
• User.destroy(‘50fd8a786bcb608e1c000002’)
• User.destroy_all
• User.destroy_all(:age.gt => 25)
Wednesday, 23 January 13
validations:
MongoMapper uses Rails ActiveModel:Validations
http://api.rubyonrails.org/classes/ActiveModel/Validations.html
Wednesday, 23 January 13
class User include MongoMapper::Document
key :name, String, required: true key :age, Integer validates_numericality_of :age
validates :age_larger_18
def age_larger_18 errors.add( :age, "too young") if age < 18 endend
Wednesday, 23 January 13
shorthands available:
:required – Boolean:unique – Boolean:numeric – Boolean:format – Regexp:in – Array:not_in – Array:length – Integer, Range, or Hash
Wednesday, 23 January 13
indexes:
Wednesday, 23 January 13
indexes: • put indexes into the initializer
Wednesday, 23 January 13
indexes: • put indexes into the initializer
• index on single field:
User.ensure_index(:name)
Wednesday, 23 January 13
indexes: • put indexes into the initializer
• index on single field:
User.ensure_index(:name)
• index multiple keys:
User.ensure_index([[:name, 1], [:age, -1]])
Wednesday, 23 January 13
indexes: • put indexes into the initializer
• index on single field:
User.ensure_index(:name)
• index multiple keys:
User.ensure_index([[:name, 1], [:age, -1]])
• the order of keys is important in compound indexes
Wednesday, 23 January 13
indexes: • put indexes into the initializer
• index on single field:
User.ensure_index(:name)
• index multiple keys:
User.ensure_index([[:name, 1], [:age, -1]])
• the order of keys is important in compound indexes
• unique index:
User.ensure_index [[:name, 1]], :unique => true
Wednesday, 23 January 13
indexes: • put indexes into the initializer
• index on single field:
User.ensure_index(:name)
• index multiple keys:
User.ensure_index([[:name, 1], [:age, -1]])
• the order of keys is important in compound indexes
• unique index:
User.ensure_index [[:name, 1]], :unique => true• delete index: User.drop_index(:name)
Wednesday, 23 January 13
using the decorator/presenter pattern for schemaless dbs
mongoDB
controller
retrieves object
decorator
‘decorates’ object for presentation
view
passes decorated object to view
Wednesday, 23 January 13