PRACTICAL
PROJECTS WITH
WHO AM I?

Alex Sharp
Lead Developer at OptimisDev

@ajsharp (on the twitters)
alexjsharp.com (on the ‘tubes)
github.com/ajsharp (on the ‘hubs)
MAJOR POINTS
• Making    the case for Mongo

• Brief   intro to MongoDB

• Practical   Projects
MAKING THE CASE
THE PROBLEMS OF SQL
A BRIEF HISTORY OF SQL

• Developed   at IBM in early 1970’s.

• Designed   to manipulate and retrieve data stored in relational
 databases
A BRIEF HISTORY OF SQL

• Developed   at IBM in early 1970’s.

• Designed   to manipulate and retrieve data stored in relational
 databases


                    this is a problem
WE DON’T WORK
 WITH DATA...
WE WORK WITH
   OBJECTS
WE DON’T CARE
    ABOUT
 STORING DATA
WE CARE ABOUT
PERSISTING STATE
DATA != OBJECTS
THEREFORE...
BOLD STATEMENT
 FORTHCOMING...
relational DBs are an
antiquated tool for our
         needs
OK, SO WHAT?
Relational schemas are designed
    to store and query data,
      not persist objects.
To reconcile this
mismatch, we have
      ORM’s
Object Relational
   Mappers
ORMs enable us to create a
  mapping between our
    native object model
  and a relational schema
We’re forced to create
   relationships for data


when what we really want is
   properties for objects.
THIS IS NOT EFFICIENT
A WEIRD EXAMPLE...
@alex = Person.new(
  :name => "alex",
  :stalkings => [
    Friend.new("Jim"),
    Friend.new("Bob")]
)
NATIVE RUBY OBJECT

<Person:0x10017d030 @name="alex",
 @stalkings=
    [#<Friend:0x10017d0a8 @name="Jim">,
     #<Friend:0x10017d058 @name="Bob">
 ]>
JSON
        REPRESENTATION
@alex.to_json
=> { name: "alex", stalkings: [{ name: "Jim" }, { name: "Bob" }] }
Relational Schema
      Representation
people:
  - name

stalkings:
  - name
  - stalker_id
  - stalkee_id
SQL Schema Representation
people:
  - name

stalkings:
  - name         What!?
  - stalker_id
  - stalkee_id
Ruby -> JSON -> SQL
       <Person:0x10017d030 @name="alex",
       @stalkings=
Ruby      [#<Friend:0x10017d0a8 @name="Jim">,
           #<Friend:0x10017d058 @name="Bob">
       ]>

       @alex.to_json
JSON   { name: "alex",
         stalkings: [{ name: "Jim" }, { name: "Bob" }]
       }


       people:
         - name
SQL    stalkings:
         - name
         - stalker_id
         - stalkee_id
Ruby -> JSON -> SQL
       <Person:0x10017d030 @name="alex",
       @stalkings=
Ruby      [#<Friend:0x10017d0a8 @name="Jim">,
           #<Friend:0x10017d058 @name="Bob">
       ]>

       @alex.to_json
JSON   { name: "alex",
         stalkings: [{ name: "Jim" }, { name: "Bob" }]
       }


       people:
         - name         Feels like we’re working
SQL    stalkings:            too hard here
         - name
         - stalker_id
         - stalkee_id
You’re probably
     thinking...

“SQL isn’t that bad”
Maybe.
But we can do better.
THE IDEAL PERSISTENCE LAYER:
THE IDEAL PERSISTENCE LAYER:

1. To persist objects in their native state
THE IDEAL PERSISTENCE LAYER:

1. To persist objects in their native state
2. Does not interfere w/ application development
THE IDEAL PERSISTENCE LAYER:

1. To persist objects in their native state
2. Does not interfere w/ application development
3. Provides features needed to build modern web
 apps
MONGO TO THE
  RESCUE!
WHAT IS MONGODB?

mongodb is a high-performance,
schema-less, scalable, document-
      oriented database
STRENGTHS
SCHEMA-LESS
SCHEMA-LESS
• Great   for rapid, iterative, agile development
SCHEMA-LESS
• Great   for rapid, iterative, agile development

• Makes   things possible that in an RDBMS are either

 a. impossibly hard

 b. virtually impossible

 c. way harder than they should be
DOCUMENT-ORIENTED
DOCUMENT-ORIENTED
• Mongo   stores documents, not rows

 • documents   are stored as binary json
DOCUMENT-ORIENTED
• Mongo   stores documents, not rows

  • documents      are stored as binary json

• Rich, familiar   query syntax
DOCUMENT-ORIENTED
• Mongo   stores documents, not rows

  • documents      are stored as binary json

• Rich, familiar   query syntax

• Embedded     documents eliminate many modeling headaches
QUERY EXAMPLES
    sample mongo document
{'status': 500,
  'request_method': 'post',
  'controller_action': 'notes#create',
  'user':
    {'first_name': 'John',
     'last_name': 'Doe'}
}
QUERY EXAMPLES

logs.find('status' => 500)

# SQL equivalent:
# select * from logs WHERE logs.status = 500


 {'status': 500,
   'request_method': 'post',
   'controller_action': 'notes#create',
   'user':
     {'first_name': 'John',
      'last_name': 'Doe'}
 }
QUERY EXAMPLES

logs.find('status' => 500, 'user.last_name' => 'Doe')

# SQL equivalent: none



 {'status': 500,
   'request_method': 'post',
   'controller_action': 'notes#create',
   'user':
     {'first_name': 'John',
      'last_name': 'Doe'}
 }
QUERY EXAMPLES

logs.find('status' => 500, 'user.last_name' => 'Doe')

{'status': 500,
  'request_method': 'post',
                                             user is an
  'controller_action': 'notes#create',   embedded document
  'user':
    {'first_name': 'John',
     'last_name': 'Doe'}
}
QUERY EXAMPLES

logs.find('status' => 500, 'user.last_name' => 'Doe')



      in sql, we would have JOIN-ed to the ‘users’ table
                       to do this query
QUERY EXAMPLES

# also works w/ regex
logs.find('request_method' => /p/i)

# SQL equivalent:
# select * from logs where request_method LIKE %p%
 {'status': 500,
   'request_method': 'post',
   'controller_action': 'notes#create',
   'user':
     {'first_name': 'John',
      'last_name': 'Doe'}
 }
BIG DATA
BIG DATA
• Built   to scale horizontally into the cloudz
BIG DATA
• Built   to scale horizontally into the cloudz

• Auto-sharding

  • set   a shard-key, a cluster of nodes, go
FAST WRITES
FAST WRITES
• In-place   updates

  • i.e. upsert
FAST WRITES
• In-place   updates

  • i.e. upsert

• Lot’s   of db commands for fast updates

  • $set, $unset, $inc, $push
UPSERT

• Update   if present, insert otherwise

  • careful: update   does a hard replace of the entire document

# initial insert
posts.save(:title => 'my post', :body => '...')

# update-in-place "upsert"
posts.save(:_id => 'post_id', :title => 'new title', :body => '...')
AGGREGATION

Map/reduce for aggregation
AGGREGATION
// map
function() {
  emit(this.controller_action, { count: 1 });
}

// reduce
function(key, values) {
  var sum = 0;
  values.forEach(function(doc) {
    sum += doc.count;
  });

    return { count: sum };
}
FAST READS
Optimize reads with indexes, just like
            an rdbms
# index is only created if it does not exist
logs.create_index('status')

# can index on embedded documents
logs.create_index('user.first_name')

# create compound indexes
logs.create_index(
  [['user.first_name', 1],
   ['user.last_name', 1]]
)
WEAKNESSES
JOINS
 nope.
MULTI-DOCUMENT
 TRANSACTIONS
     no-sir-ee.
RELATIONAL
 INTEGRITY
  not a chance.
PRACTICAL
 PROJECTS
1. Accounting Application
2. Capped Collection Logging
3. Blogging app
GENERAL LEDGER
 ACCOUNTING
 APPLICATION
THE OBJECT MODEL
        ledger


            *
      transactions


            *
        entries
THE OBJECT MODEL
                #       Credits                       Debits



Line item   {   1
                    { :account => “Cash”,
                     :amount => 100.00 }
                                             { :account => “Notes Pay.”,
                                                  :amount => 100.00 }


                                 Ledger Entries
Line item   {   2
                    { :account => “A/R”,
                      :amount => 25.00 }
                                            { :account => “Gross Revenue”,
                                                   :amount => 25.00 }
THE OBJECT MODEL
THE OBJECT MODEL
• Each   ledger line item belongs to a ledger
THE OBJECT MODEL
• Each   ledger line item belongs to a ledger

• Each   ledger line item has two (or more) ledger entries

 • must    have at least one credit and one debit

 • credits   and debits must balance
THE OBJECT MODEL
• Each   ledger line item belongs to a ledger

• Each   ledger line item has two (or more) ledger entries

 • must    have at least one credit and one debit

 • credits   and debits must balance

• These   objects must be transactional
SQL-BASED OBJECT MODEL
@debit = Entry.new(:account => 'Cash',
  :amount => 100.00, :type => 'credit')

@credit = Entry.new(:account => 'Notes Pay.',
  :amount => 100.00, :type => 'debit')


@line_item = LineItem.new(:ledger_id => 1,
  :entries => [@debit, @credit])
SQL-BASED OBJECT MODEL
@debit = Entry.new(:account => 'Cash',
  :amount => 100.00, :type => 'credit')

@credit = Entry.new(:account => 'Notes Pay.',
  :amount => 100.00, :type => 'debit')

@line_item = LineItem.new :ledger_id => 1, :entries => [@debit, @credit]



     In a relational schema, we need a database
      transaction to ensure multi-row atomicity
SQL-BASED OBJECT MODEL
@debit = Entry.new(:account => 'Cash',
  :amount => 100.00, :type => 'credit')

@credit = Entry.new(:account => 'Notes Pay.',
  :amount => 100.00, :type => 'debit')

@line_item = LineItem.new :ledger_id => 1, :entries => [@debit, @credit]



   Because we need to create 3 new records in
               the database here
MONGO-FIED MODELING
@line_item = LineItem.new(:ledger_id => 1,
  :entries => [
    {:account => 'Cash',       :type => 'debit', :amount => 100},
    {:account => 'Notes pay.', :type => 'debit', :amount => 100}
  ]
)
MONGO-FIED MODELING
@line_item = LineItem.new(:ledger_id => 1,
  :entries => [
    {:account => 'Cash',       :type => 'debit', :amount => 100},
    {:account => 'Notes pay.', :type => 'debit', :amount => 100}
  ]
)

      This is the perfect case for embedded documents.
MONGO-FIED MODELING
@line_item = LineItem.new(:ledger_id => 1,
  :entries => [
    {:account => 'Cash',       :type => 'debit', :amount => 100},
    {:account => 'Notes pay.', :type => 'debit', :amount => 100}
  ]
)

  We will never have more than a few entries (usually two)
MONGO-FIED MODELING
@line_item = LineItem.new(:ledger_id => 1,
  :entries => [
    {:account => 'Cash',       :type => 'debit', :amount => 100},
    {:account => 'Notes pay.', :type => 'debit', :amount => 100}
  ]
)
          Embedded docs are perfect for “contains”
                   many relationships
MONGO-FIED MODELING
@line_item = LineItem.new(:ledger_id => 1,
  :entries => [
    {:account => 'Cash',       :type => 'debit', :amount => 100},
    {:account => 'Notes pay.', :type => 'debit', :amount => 100}
  ]
)
           DB-level transactions no-longer needed.
            Mongo has single document atomicity.
WINS
WINS
• Simplified, de-normalized   data model
 • Objects   modeled differently in Mongo than SQL
WINS
• Simplified, de-normalized   data model
 • Objects   modeled differently in Mongo than SQL
• Simpler   data model + no transactions = WIN
LOGGING WITH
   CAPPED
 COLLECTIONS
BASELESS STATISTIC
 95% of the time logs are NEVER used.
MOST LOGS ARE ONLY USED
 WHEN SOMETHING GOES
       WRONG
CAPPED COLLECTIONS
 • Fixed-sized, limited
                    operation, auto age-out collections
  (kinda like memcached, except persistent)

 • Fixed   insertion order

 • Super    fast (faster than normal writes)

 • Ideal   for logging and caching
GREAT. WHAT’S THAT MEAN?
We can log additional pieces of arbitrary data
effortlessly due to Mongo’s schemaless nature.
THIS IS AWESOME
CAPTURE.
 QUERY.
ANALYZE.
PROFIT.
ALSO A REALLY HANDY
 TROUBLESHOOTING
        TOOL
User-reported errors are
  difficult to diagnose
Wouldn’t it be useful to see
 the complete click-path?
BUNYAN
    http://github.com/ajsharp/bunyan




 Thin ruby layer around a
MongoDB capped collection
BUNYAN
    http://github.com/ajsharp/bunyan


Still needs a middleware api.
    Want to contribute?
require 'bunyan'

Bunyan::Logger.configure do
  database   'my_bunyan_db'
  collection "#{Rails.env}_bunyan_log"
  size       1073741824 # 1.gigabyte
end
PAPERMILL
      http://github.com/ajsharp/papermill




SINATRA FRONT-END TO BUNYAN
PAPERMILL
http://github.com/ajsharp/papermill




DEMO TIME
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
BLOGGING
APPLICATION
BLOGGING APPLICATION

Much easier to model with Mongo
   than a relational database
BLOGGING APPLICATION

   A post has an author
BLOGGING APPLICATION

   A post has an author
   A post has many tags
BLOGGING APPLICATION

                 A post has an author

                 A post has many tags

A post has many comments
BLOGGING APPLICATION
A post has an author

A post has many tags

A post has many comments
     Instead of joining separate tables,
    we can use embedded documents.
MONGOMAPPER
MONGOMAPPER
•MongoDB “ORM” developed by John Nunemaker
MONGOMAPPER
•MongoDB “ORM” developed by John Nunemaker
•Very similar syntax to DataMapper
MONGOMAPPER
•MongoDB “ORM” developed by John Nunemaker
•Very similar syntax to DataMapper
 •Declarative rather than inheritance-based
MONGOMAPPER
•MongoDB “ORM” developed by John Nunemaker
•Very similar syntax to DataMapper
  •Declarative rather than inheritance-based
•Very easy to drop into rails
MONGOMAPPER
require 'mongo'
connection = Mongo::Connection.new.db("blog_app")

class Post
  include MongoMapper::Document

  belongs_to :author, :class_name => "User"

  key :title,          String,    :required => true
  key :body,           String,    :required => true
  key :author_id,      Integer,   :required => true
  key :published_at,   Time
  key :published,      Boolean,   :default => false
  key :tags,           Array,     :default => []
  timestamps!
end
INDEXES!

Post.collection.create_index('tags')

Post.collection.create_index('title')
WINS
WINS

Simpler persistence model matches simple object
                     model
NEXT STEPS
OBJECT-DOCUMENT MAPPERS
• Ruby   mongo driver

 • github.com/mongodb/mongo-ruby-driver

• MongoMapper

 • github.com/jnunemaker/mongomapper

• Mongoid

 • github.com/durran/mongoid
MONGOMAPPER
• DataMapper-like API

• good   for moving from a sql schema to mongo

• easy   to drop into rails

• works   with rails 3
MONGOID
• DataMapper-like API

• uses ActiveModel, so      familiar validation syntax

• more     opinionated towards embedded docs

• easy    to drop into rails

• rails   2 - mongoid 1.x

• rails   3 - mongoid 2.x
mongodb.org
MOST IMPORTANTLY

           ...
WE MUST ARRIVE AT THE
 WHISKEY BAR EARLIER
    TOMORROW
BECAUSE IT CLOSES AT
    MIDNIGHT
        ;-)
QUESTIONS?
THANKS!

More Related Content

KEY
Practical Ruby Projects with MongoDB - MongoSF
KEY
Practical Ruby Projects (Alex Sharp)
PDF
Introduction to Active Record - Silicon Valley Ruby Conference 2007
PPTX
jQuery
PPTX
Art of Javascript
PDF
Intoduction to php restful web service
PPTX
jQuery
PDF
Learning jQuery in 30 minutes
Practical Ruby Projects with MongoDB - MongoSF
Practical Ruby Projects (Alex Sharp)
Introduction to Active Record - Silicon Valley Ruby Conference 2007
jQuery
Art of Javascript
Intoduction to php restful web service
jQuery
Learning jQuery in 30 minutes

What's hot (20)

PPT
JQuery introduction
PDF
MVS: An angular MVC
PDF
Contagion的Ruby/Rails投影片
 
PPTX
jQuery from the very beginning
PDF
jQuery Essentials
PPTX
J query1
PPT
J query
PPTX
jQuery Fundamentals
PDF
Symfony Day 2010 Doctrine MongoDB ODM
PPTX
PDF
Learning jQuery made exciting in an interactive session by one of our team me...
PDF
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
PDF
ZendCon2010 Doctrine MongoDB ODM
PDF
Doctrine MongoDB Object Document Mapper
ODP
Introduction to jQuery
PDF
A single language for backend and frontend from AngularJS to cloud with Clau...
PPT
PDF
The Dom Scripting Toolkit J Query
PPTX
PDF
jQuery for beginners
JQuery introduction
MVS: An angular MVC
Contagion的Ruby/Rails投影片
 
jQuery from the very beginning
jQuery Essentials
J query1
J query
jQuery Fundamentals
Symfony Day 2010 Doctrine MongoDB ODM
Learning jQuery made exciting in an interactive session by one of our team me...
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
ZendCon2010 Doctrine MongoDB ODM
Doctrine MongoDB Object Document Mapper
Introduction to jQuery
A single language for backend and frontend from AngularJS to cloud with Clau...
The Dom Scripting Toolkit J Query
jQuery for beginners
Ad

Viewers also liked (6)

PDF
Estácio: 4Q12 and 2012 Conference Call Presentation
PPT
Dog-eat-dog 02 - Flash or Not
PDF
C31 college 2
PDF
Dialoog & digiloog, suggesties voor interne communicatie
PDF
Social Responsibility - a Reprints Desk Presentation
PPT
Grecia Escultura 2014
Estácio: 4Q12 and 2012 Conference Call Presentation
Dog-eat-dog 02 - Flash or Not
C31 college 2
Dialoog & digiloog, suggesties voor interne communicatie
Social Responsibility - a Reprints Desk Presentation
Grecia Escultura 2014
Ad

Similar to Practical Ruby Projects with MongoDB - Ruby Kaigi 2010 (20)

KEY
Practical Ruby Projects With Mongo Db
PDF
Relationships are hard
PDF
Tame Accidental Complexity with Ruby and MongoMapper
KEY
MongoDB - Ruby document store that doesn't rhyme with ouch
PDF
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
PDF
Rails israel 2013
PDF
MongoDB at FrozenRails
PDF
Navigating the Transition from relational to NoSQL - CloudCon Expo 2012
PDF
Transition from relational to NoSQL Philly DAMA Day
ZIP
Rails and alternative ORMs
PDF
The State of NoSQL
PPTX
Intro to RavenDB
PPT
No sql
PDF
DataMapper
PDF
NoSQL @ CodeMash 2010
KEY
MongoDB at RubyEnRails 2009
PDF
Mongodb my
PDF
MongoDB
PDF
NoSQL overview #phptostart turin 11.07.2011
Practical Ruby Projects With Mongo Db
Relationships are hard
Tame Accidental Complexity with Ruby and MongoMapper
MongoDB - Ruby document store that doesn't rhyme with ouch
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
Rails israel 2013
MongoDB at FrozenRails
Navigating the Transition from relational to NoSQL - CloudCon Expo 2012
Transition from relational to NoSQL Philly DAMA Day
Rails and alternative ORMs
The State of NoSQL
Intro to RavenDB
No sql
DataMapper
NoSQL @ CodeMash 2010
MongoDB at RubyEnRails 2009
Mongodb my
MongoDB
NoSQL overview #phptostart turin 11.07.2011

More from Alex Sharp (9)

PDF
Bldr: A Minimalist JSON Templating DSL
PDF
Bldr - Rubyconf 2011 Lightning Talk
PDF
Mysql to mongo
PDF
Refactoring in Practice - Sunnyconf 2010
PDF
Refactoring in Practice - Ruby Hoedown 2010
PDF
Practical Ruby Projects with MongoDB - Ruby Midwest
PDF
Intro To MongoDB
KEY
Getting Comfortable with BDD
KEY
Testing Has Many Purposes
Bldr: A Minimalist JSON Templating DSL
Bldr - Rubyconf 2011 Lightning Talk
Mysql to mongo
Refactoring in Practice - Sunnyconf 2010
Refactoring in Practice - Ruby Hoedown 2010
Practical Ruby Projects with MongoDB - Ruby Midwest
Intro To MongoDB
Getting Comfortable with BDD
Testing Has Many Purposes

Recently uploaded (20)

PPT
Module 1.ppt Iot fundamentals and Architecture
PPTX
Final SEM Unit 1 for mit wpu at pune .pptx
PPTX
observCloud-Native Containerability and monitoring.pptx
PDF
A review of recent deep learning applications in wood surface defect identifi...
PDF
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
PDF
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
PDF
Hybrid model detection and classification of lung cancer
PPTX
Group 1 Presentation -Planning and Decision Making .pptx
PDF
STKI Israel Market Study 2025 version august
PPTX
Tartificialntelligence_presentation.pptx
PDF
Enhancing emotion recognition model for a student engagement use case through...
PDF
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
PDF
A comparative study of natural language inference in Swahili using monolingua...
PPTX
Chapter 5: Probability Theory and Statistics
PDF
Hindi spoken digit analysis for native and non-native speakers
PDF
Five Habits of High-Impact Board Members
PDF
DASA ADMISSION 2024_FirstRound_FirstRank_LastRank.pdf
PDF
Univ-Connecticut-ChatGPT-Presentaion.pdf
PDF
A novel scalable deep ensemble learning framework for big data classification...
PPTX
O2C Customer Invoices to Receipt V15A.pptx
Module 1.ppt Iot fundamentals and Architecture
Final SEM Unit 1 for mit wpu at pune .pptx
observCloud-Native Containerability and monitoring.pptx
A review of recent deep learning applications in wood surface defect identifi...
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
Transform Your ITIL® 4 & ITSM Strategy with AI in 2025.pdf
Hybrid model detection and classification of lung cancer
Group 1 Presentation -Planning and Decision Making .pptx
STKI Israel Market Study 2025 version august
Tartificialntelligence_presentation.pptx
Enhancing emotion recognition model for a student engagement use case through...
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
A comparative study of natural language inference in Swahili using monolingua...
Chapter 5: Probability Theory and Statistics
Hindi spoken digit analysis for native and non-native speakers
Five Habits of High-Impact Board Members
DASA ADMISSION 2024_FirstRound_FirstRank_LastRank.pdf
Univ-Connecticut-ChatGPT-Presentaion.pdf
A novel scalable deep ensemble learning framework for big data classification...
O2C Customer Invoices to Receipt V15A.pptx

Practical Ruby Projects with MongoDB - Ruby Kaigi 2010