SlideShare a Scribd company logo
PRACTICAL
                          PROJECTS WITH



Saturday, July 17, 2010
WHO AM I?

       Alex Sharp
       Lead Developer at OptimisDev

       @ajsharp (on the twitters)
       alexjsharp.com (on the ‘tubes)
       github.com/ajsharp (on the ‘hubs)




Saturday, July 17, 2010
MAJOR POINTS
    • Brief           intro to MongoDB

    • Practical            Projects

    • Making              the case for Mongo (time permitting)




Saturday, July 17, 2010
BRIEF INTRO


Saturday, July 17, 2010
WHAT IS MONGODB?
            mongodb is a high-performance, schema-less,
                  document-oriented database




Saturday, July 17, 2010
STRENGTHS


Saturday, July 17, 2010
SCHEMA-LESS




Saturday, July 17, 2010
SCHEMA-LESS
    • Great               for rapid, iterative, agile development




Saturday, July 17, 2010
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




Saturday, July 17, 2010
DOCUMENT-ORIENTED




Saturday, July 17, 2010
DOCUMENT-ORIENTED
    • Mongo               stores documents, not rows

         • documents           are stored as binary json




Saturday, July 17, 2010
DOCUMENT-ORIENTED
    • Mongo               stores documents, not rows

         • documents            are stored as binary json

    • Allows              for a rich query syntax




Saturday, July 17, 2010
DOCUMENT-ORIENTED
    • Mongo               stores documents, not rows

         • documents            are stored as binary json

    • Allows              for a rich query syntax

    • Embedded                documents eliminate many modeling headaches




Saturday, July 17, 2010
BIG DATA




Saturday, July 17, 2010
BIG DATA
    • Built           to scale horizontally into the cloudz




Saturday, July 17, 2010
BIG DATA
    • Built           to scale horizontally into the cloudz

    • Auto-sharding

         • set            a shard-key, a cluster of nodes, go

         • still          in alpha, but production-ready soon




Saturday, July 17, 2010
FAST WRITES




Saturday, July 17, 2010
FAST WRITES
    • Mongo                writes are “fire-and-forget”

         • you            can get a response with getLastError()




Saturday, July 17, 2010
FAST WRITES
    • Mongo                writes are “fire-and-forget”

         • you            can get a response with getLastError()

    • In-place             updates




Saturday, July 17, 2010
FAST WRITES
    • Mongo                 writes are “fire-and-forget”

         • you            can get a response with getLastError()

    • In-place              updates

    • Lot’s               of db commands for fast updates




Saturday, July 17, 2010
AGGREGATION
                            Map/reduce for aggregation




Saturday, July 17, 2010
READS FAST TOO
                          Optimize reads with indexes, just like an rdbms




Saturday, July 17, 2010
WEAKNESSES




Saturday, July 17, 2010
JOINS
                           nope.




Saturday, July 17, 2010
MULTI-DOCUMENT
                  TRANSACTIONS
                          no-sir-ee.




Saturday, July 17, 2010
RELATIONAL
                           INTEGRITY
                            not a chance.




Saturday, July 17, 2010
PRACTICAL
                           PROJECTS



Saturday, July 17, 2010
1. Accounting Application
    2. Capped Collection Logging
    3. Blogging app
    4. Reporting app



Saturday, July 17, 2010
GENERAL LEDGER
                       ACCOUNTING
                       APPLICATION


Saturday, July 17, 2010
THE OBJECT MODEL
                            ledger


                                *
                          transactions


                                *
                            entries




Saturday, July 17, 2010
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 }




Saturday, July 17, 2010
THE OBJECT MODEL




Saturday, July 17, 2010
THE OBJECT MODEL
    • Each                ledger line item belongs to a ledger




Saturday, July 17, 2010
THE OBJECT MODEL
    • Each                ledger line item belongs to a ledger

    • Each                ledger line item has two ledger entries

         • must             have at least one credit and one debit

         • credits            and debits must balance




Saturday, July 17, 2010
THE OBJECT MODEL
    • Each                ledger line item belongs to a ledger

    • Each                ledger line item has two ledger entries

         • must             have at least one credit and one debit

         • credits            and debits must balance

    • These                objects must be transactional



Saturday, July 17, 2010
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]




Saturday, July 17, 2010
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 SQL schema, we need a database
               transaction to ensure multi-row atomicity

Saturday, July 17, 2010
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]



    Remember: we have to create 3 new records in
                the database here

Saturday, July 17, 2010
MONGO-FIED MODELING
 @line_item = LineItem.new(:ledger_id => 1,
   :entries => [
     {:account => 'Cash',       :type => 'debit', :amount => 100},
     {:account => 'Notes pay.', :type => 'debit', :amount => 100}
   ]
 )




Saturday, July 17, 2010
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.




Saturday, July 17, 2010
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)




Saturday, July 17, 2010
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




Saturday, July 17, 2010
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.




Saturday, July 17, 2010
LESSONS




Saturday, July 17, 2010
LESSONS
 • Simplified, de-normalized             data model
       • Objects          modeled differently in Mongo than SQL




Saturday, July 17, 2010
LESSONS
 • Simplified, de-normalized              data model
       • Objects           modeled differently in Mongo than SQL
 • Simpler                data model + no transactions = WIN




Saturday, July 17, 2010
LOGGING WITH
                             CAPPED
                           COLLECTIONS


Saturday, July 17, 2010
BASELESS STATISTIC
                          95% of the time logs are NEVER used.




Saturday, July 17, 2010
MOST LOGS ARE ONLY USED
        WHEN SOMETHING GOES
              WRONG




Saturday, July 17, 2010
CAPPED COLLECTIONS
                • Fixed-sized, limitedoperation, auto age-out collections
                    (kinda like memcached, except persistent)

                • Fixed   insertion order

                • Super    fast (faster than normal writes)

                • Ideal   for logging and caching




Saturday, July 17, 2010
GREAT. WHAT’S THAT MEAN?
           We can log additional pieces of arbitrary data
           effortlessly due to Mongo’s schemaless nature.




Saturday, July 17, 2010
THIS IS AWESOME



Saturday, July 17, 2010
QUERY. ANALYZE. PROFIT.




Saturday, July 17, 2010
ALSO A REALLY HANDY
             TROUBLESHOOTING TOOL




Saturday, July 17, 2010
User-reported errors are difficult to
                       diagnose




Saturday, July 17, 2010
Wouldn’t it be useful to see the complete click-
                                 path?




Saturday, July 17, 2010
BUNYAN
                              http://github.com/ajsharp/bunyan


                           Thin ruby layer around a
                          MongoDB capped collection




Saturday, July 17, 2010
BUNYAN
                              http://github.com/ajsharp/bunyan


                          Still needs a middleware api.
                              Want to contribute?




Saturday, July 17, 2010
require 'bunyan'

       Bunyan::Logger.configure do |c|
         c.database   'my_bunyan_db'
         c.collection "#{Rails.env}_bunyan_log"
         c.size 1073741824 # 1.gigabyte
       end




Saturday, July 17, 2010
PAPERMILL
                          http://github.com/ajsharp/papermill



   SINATRA FRONT-END TO BUNYAN




Saturday, July 17, 2010
BLOGGING
                          APPLICATION



Saturday, July 17, 2010
BLOGGING APPLICATION

        Much easier to model with Mongo than a relational database




Saturday, July 17, 2010
BLOGGING APPLICATION

        A post has an author




Saturday, July 17, 2010
BLOGGING APPLICATION

        A post has an author

        A post has many tags




Saturday, July 17, 2010
BLOGGING APPLICATION

        A post has an author

        A post has many tags

         A post has many comments




Saturday, July 17, 2010
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.




Saturday, July 17, 2010
MONGOMAPPER




Saturday, July 17, 2010
MONGOMAPPER
    •MongoDB “ORM” developed by John Nunemaker




Saturday, July 17, 2010
MONGOMAPPER
    •MongoDB “ORM” developed by John Nunemaker
    •Very similar syntax to DataMapper




Saturday, July 17, 2010
MONGOMAPPER
    •MongoDB “ORM” developed by John Nunemaker
    •Very similar syntax to DataMapper
         •Declarative rather than inheritance-based




Saturday, July 17, 2010
MONGOMAPPER
    •MongoDB “ORM” developed by John Nunemaker
    •Very similar syntax to DataMapper
         •Declarative rather than inheritance-based
    •Very easy to drop into rails




Saturday, July 17, 2010
MONGOMAPPER
   require 'mongo'
   connection = Mongo::Connection.new.db("#{Rails.env}_app")

   class Post
     include MongoMapper::Document

          belongs_to :author, :class_name => "User"

     key :title,             String,    :reuqired => 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

Saturday, July 17, 2010
REPORTING APP




Saturday, July 17, 2010
Saturday, July 17, 2010
REPORTING IS HARD
    • Synchronization

         • Data, application API, schema

    • Schema              synchronization is the hard one




Saturday, July 17, 2010
WHY MONGO?
    • Aggregation              support with Mongo’s map/reduce support

    • Mongo               is good (and getting better) at handling big data sets

    • Schemaless              is perfect for a flattened data set




Saturday, July 17, 2010
Amazon EC2          Rackspace



                                                 Transform
                          MongoDB Server

                           Reporting App
                                           WAN   Main App

                                                  MySQL




Saturday, July 17, 2010
CLIENT REQUESTS         Amazon EC2



                                       MongoDB Server

                                                  map/reduce

                                         Reporting App



                                                                    User requests
                          Client request GET /reports/some_report




Saturday, July 17, 2010
TRANFORMATION
           Data needs to extracted from the the main app,
           transormed (i.e. flattened) into some other form,
                and loaded into the reporting app for
                               aggregation




Saturday, July 17, 2010
TRANSFORMATION
                          Rackspace                                                  Amazon EC2

                                         1. GET /object_dependencies
                          Transform                                              MongoDB Server
                                      { :visit => [ :insurances, :patients ] }
                                                                                     2. read from
                                                                                        active record


                           MySQL
                                                2. write to mongo                Reporting App
                          Main App




Saturday, July 17, 2010
MAKING THE CASE



Saturday, July 17, 2010
THE PROBLEMS OF SQL


Saturday, July 17, 2010
A BRIEF HISTORY OF SQL

    • Developed            at IBM in early 1970’s.

    • Designed            to manipulate and retrieve data stored in relational
        databases




Saturday, July 17, 2010
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




Saturday, July 17, 2010
WHY??


Saturday, July 17, 2010
WE DON’T WORK WITH
                           DATA...



Saturday, July 17, 2010
WE WORK WITH OBJECTS




Saturday, July 17, 2010
WE DON’T CARE
                              ABOUT
                           STORING DATA


Saturday, July 17, 2010
WE CARE ABOUT
                          PERSISTING STATE



Saturday, July 17, 2010
DATA != OBJECTS


Saturday, July 17, 2010
THEREFORE...


Saturday, July 17, 2010
RELATIONAL DBS ARE AN
    ANTIQUATED TOOL FOR OUR
             NEEDS



Saturday, July 17, 2010
OK, SO WHAT?
                     SQL schemas are designed for storing and
                       querying data, not persisting objects.




Saturday, July 17, 2010
To reconcile this
                          mismatch, we have
                                ORM’s


Saturday, July 17, 2010
Object Relational
                             Mappers


Saturday, July 17, 2010
OK, SO WHAT?
               We need ORMs to bridge the gap
                (map) between our native Ruby
               object model and a SQL schema




Saturday, July 17, 2010
We’re forced to create relationships for data
            when what we really want is properties for our
                              objects.




Saturday, July 17, 2010
THIS IS NOT EFFICIENT


Saturday, July 17, 2010
@alex = Person.new(
                    :name => "alex",
                    :stalkings => [
                      Friend.new("Jim"),
                      Friend.new("Bob")]
                  )


Saturday, July 17, 2010
Native ruby object


 <Person:0x10017d030 @name="alex",
   @stalkings=
      [#<Friend:0x10017d0a8 @name="Jim">,
       #<Friend:0x10017d058 @name="Bob">
   ]>




Saturday, July 17, 2010
JSON/Mongo Representation

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




Saturday, July 17, 2010
SQL Schema Representation
         people:
           - name

         stalkings:
           - name
           - stalker_id

Saturday, July 17, 2010
SQL Schema Representation
           people:
             - name

           stalkings:         What!?
             - name
             - stalker_id

Saturday, July 17, 2010
SQL Schema Representation
             people:
               - name

             stalkings:
                              what’s a stalker_id?
               - name
               - stalker_id

Saturday, July 17, 2010
SQL Schema Representation
             people:
               - name

             stalkings:
                              this is our sql mapping
               - name
               - stalker_id

Saturday, July 17, 2010
SQL Schema Representation
             people:
               - name

             stalkings:         this is the
               - name         “pointless” join
               - stalker_id

Saturday, July 17, 2010
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



Saturday, July 17, 2010
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 having
        SQL               stalkings:       to work too hard here
                            - name
                            - stalker_id



Saturday, July 17, 2010
You’re probably thinking...
                    “Listen GUY, SQL isn’t that bad”




Saturday, July 17, 2010
Maybe.




Saturday, July 17, 2010
But we can do much, much better.




Saturday, July 17, 2010
NEEDS FOR A PERSISTENCE
                     LAYER:




Saturday, July 17, 2010
NEEDS FOR A PERSISTENCE
                     LAYER:
    1. To persist the native state of our objects




Saturday, July 17, 2010
NEEDS FOR A PERSISTENCE
                     LAYER:
    1. To persist the native state of our objects

    2. Should NOT interfere w/ application development




Saturday, July 17, 2010
NEEDS FOR A PERSISTENCE
                     LAYER:
    1. To persist the native state of our objects

    2. Should NOT interfere w/ application development

    3. Provides features necessary to build modern web apps




Saturday, July 17, 2010
NEXT STEPS



Saturday, July 17, 2010
USING MONGO W/ RUBY
    • Ruby                mongo driver

    • MongoMapper                 (github.com/jnunemaker/mongomapper)

    • MongoID                (github.com/durran/mongoid)

    • Many                other ORM/ODM’s

         • mongo-sequel            (github.com/jeremyevans/sequel-mongo)

         • moneta             (github.com/wycats/moneta)


Saturday, July 17, 2010
MONGOMAPPER
    • DataMapper-like API

    • good                for moving from a sql schema to mongo

    • easy            to drop into rails

    • works               with rails 3




Saturday, July 17, 2010
MONGOID
    • DataMapper-like API

    • uses ActiveModel, so             familiar validation syntax

    • more                opinionated embedded docs

    • easy            to drop into rails

    • rails          2 - mongoid 1.x

    • rails          3 - mongoid 2.x


Saturday, July 17, 2010
QUESTIONS?




Saturday, July 17, 2010
THANKS!




Saturday, July 17, 2010
Ad

Recommended

Schema Design
Schema Design
MongoDB
 
Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)
MongoSF
 
MongoDB on Windows Azure
MongoDB on Windows Azure
MongoDB
 
MongoHQ (Jason McCay & Ben Wyrosdick)
MongoHQ (Jason McCay & Ben Wyrosdick)
MongoSF
 
MongoDB - Ruby document store that doesn't rhyme with ouch
MongoDB - Ruby document store that doesn't rhyme with ouch
Wynn Netherland
 
MongoDB Replication (Dwight Merriman)
MongoDB Replication (Dwight Merriman)
MongoSF
 
Cosmic rays detection theory
Cosmic rays detection theory
Lalit Pradhan
 
Cosmic Ray Presentation
Cosmic Ray Presentation
guest3aa2df
 
physics lecture
physics lecture
Jolie John Ej Cadag
 
MongoDB: How it Works
MongoDB: How it Works
Mike Dirolf
 
Solid state physics - Crystalline Solids
Solid state physics - Crystalline Solids
Athren Tidalgo
 
The Right (and Wrong) Use Cases for MongoDB
The Right (and Wrong) Use Cases for MongoDB
MongoDB
 
MongoDB Advanced Schema Design - Inboxes
MongoDB Advanced Schema Design - Inboxes
Jared Rosoff
 
Building a Social Network with MongoDB
Building a Social Network with MongoDB
Fred Chu
 
Modeling Data in MongoDB
Modeling Data in MongoDB
lehresman
 
MongoDB Schema Design
MongoDB Schema Design
MongoDB
 
Common MongoDB Use Cases
Common MongoDB Use Cases
MongoDB
 
MongoDB Schema Design: Four Real-World Examples
MongoDB Schema Design: Four Real-World Examples
Mike Friedman
 
Node.js and Ruby
Node.js and Ruby
Michael Bleigh
 
Practical Ruby Projects (Alex Sharp)
Practical Ruby Projects (Alex Sharp)
MongoSF
 
Practical Ruby Projects with MongoDB - MongoSF
Practical Ruby Projects with MongoDB - MongoSF
Alex Sharp
 
Practical Ruby Projects With Mongo Db
Practical Ruby Projects With Mongo Db
Alex Sharp
 
GGUG:Practical DSL Design
GGUG:Practical DSL Design
Skills Matter
 
Is these a bug
Is these a bug
Mike Taylor
 
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
Alex Sharp
 
Deciphering the Interoperable Web
Deciphering the Interoperable Web
Michael Bleigh
 
QueryPath: It's like PHP jQuery in Drupal!
QueryPath: It's like PHP jQuery in Drupal!
Matt Butcher
 
Mongo db
Mongo db
Antonio Terreno
 
Html5 coredevsummit
Html5 coredevsummit
Jen Simmons
 
Unobtrusive CSS
Unobtrusive CSS
John Hwang
 

More Related Content

Viewers also liked (10)

physics lecture
physics lecture
Jolie John Ej Cadag
 
MongoDB: How it Works
MongoDB: How it Works
Mike Dirolf
 
Solid state physics - Crystalline Solids
Solid state physics - Crystalline Solids
Athren Tidalgo
 
The Right (and Wrong) Use Cases for MongoDB
The Right (and Wrong) Use Cases for MongoDB
MongoDB
 
MongoDB Advanced Schema Design - Inboxes
MongoDB Advanced Schema Design - Inboxes
Jared Rosoff
 
Building a Social Network with MongoDB
Building a Social Network with MongoDB
Fred Chu
 
Modeling Data in MongoDB
Modeling Data in MongoDB
lehresman
 
MongoDB Schema Design
MongoDB Schema Design
MongoDB
 
Common MongoDB Use Cases
Common MongoDB Use Cases
MongoDB
 
MongoDB Schema Design: Four Real-World Examples
MongoDB Schema Design: Four Real-World Examples
Mike Friedman
 
MongoDB: How it Works
MongoDB: How it Works
Mike Dirolf
 
Solid state physics - Crystalline Solids
Solid state physics - Crystalline Solids
Athren Tidalgo
 
The Right (and Wrong) Use Cases for MongoDB
The Right (and Wrong) Use Cases for MongoDB
MongoDB
 
MongoDB Advanced Schema Design - Inboxes
MongoDB Advanced Schema Design - Inboxes
Jared Rosoff
 
Building a Social Network with MongoDB
Building a Social Network with MongoDB
Fred Chu
 
Modeling Data in MongoDB
Modeling Data in MongoDB
lehresman
 
MongoDB Schema Design
MongoDB Schema Design
MongoDB
 
Common MongoDB Use Cases
Common MongoDB Use Cases
MongoDB
 
MongoDB Schema Design: Four Real-World Examples
MongoDB Schema Design: Four Real-World Examples
Mike Friedman
 

Similar to Practical Ruby Projects with MongoDB - Ruby Midwest (20)

Node.js and Ruby
Node.js and Ruby
Michael Bleigh
 
Practical Ruby Projects (Alex Sharp)
Practical Ruby Projects (Alex Sharp)
MongoSF
 
Practical Ruby Projects with MongoDB - MongoSF
Practical Ruby Projects with MongoDB - MongoSF
Alex Sharp
 
Practical Ruby Projects With Mongo Db
Practical Ruby Projects With Mongo Db
Alex Sharp
 
GGUG:Practical DSL Design
GGUG:Practical DSL Design
Skills Matter
 
Is these a bug
Is these a bug
Mike Taylor
 
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
Alex Sharp
 
Deciphering the Interoperable Web
Deciphering the Interoperable Web
Michael Bleigh
 
QueryPath: It's like PHP jQuery in Drupal!
QueryPath: It's like PHP jQuery in Drupal!
Matt Butcher
 
Mongo db
Mongo db
Antonio Terreno
 
Html5 coredevsummit
Html5 coredevsummit
Jen Simmons
 
Unobtrusive CSS
Unobtrusive CSS
John Hwang
 
Building Distributed JavaScript Widgets with jQuery
Building Distributed JavaScript Widgets with jQuery
benvinegar
 
Human APIs
Human APIs
Nikolai Onken
 
Big Data loves JS
Big Data loves JS
Dominiek ter Heide
 
When is a Website Not Enough? Now.
When is a Website Not Enough? Now.
bethgsanders
 
Mathias test
Mathias test
Mathias Stjernström
 
noSQL @ QCon SP
noSQL @ QCon SP
Alexandre Porcelli
 
Reporting, the easy way
Reporting, the easy way
Will Trillich
 
Human APIs - expanding the mobile web or are robots coming to JavaScript?
Human APIs - expanding the mobile web or are robots coming to JavaScript?
Nikolai Onken
 
Practical Ruby Projects (Alex Sharp)
Practical Ruby Projects (Alex Sharp)
MongoSF
 
Practical Ruby Projects with MongoDB - MongoSF
Practical Ruby Projects with MongoDB - MongoSF
Alex Sharp
 
Practical Ruby Projects With Mongo Db
Practical Ruby Projects With Mongo Db
Alex Sharp
 
GGUG:Practical DSL Design
GGUG:Practical DSL Design
Skills Matter
 
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
Practical Ruby Projects with MongoDB - Ruby Kaigi 2010
Alex Sharp
 
Deciphering the Interoperable Web
Deciphering the Interoperable Web
Michael Bleigh
 
QueryPath: It's like PHP jQuery in Drupal!
QueryPath: It's like PHP jQuery in Drupal!
Matt Butcher
 
Html5 coredevsummit
Html5 coredevsummit
Jen Simmons
 
Unobtrusive CSS
Unobtrusive CSS
John Hwang
 
Building Distributed JavaScript Widgets with jQuery
Building Distributed JavaScript Widgets with jQuery
benvinegar
 
When is a Website Not Enough? Now.
When is a Website Not Enough? Now.
bethgsanders
 
Reporting, the easy way
Reporting, the easy way
Will Trillich
 
Human APIs - expanding the mobile web or are robots coming to JavaScript?
Human APIs - expanding the mobile web or are robots coming to JavaScript?
Nikolai Onken
 
Ad

More from Alex Sharp (8)

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

Recently uploaded (20)

MuleSoft for AgentForce : Topic Center and API Catalog
MuleSoft for AgentForce : Topic Center and API Catalog
shyamraj55
 
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance
 
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Alliance
 
Wenn alles versagt - IBM Tape schützt, was zählt! Und besonders mit dem neust...
Wenn alles versagt - IBM Tape schützt, was zählt! Und besonders mit dem neust...
Josef Weingand
 
Smarter Aviation Data Management: Lessons from Swedavia Airports and Sweco
Smarter Aviation Data Management: Lessons from Swedavia Airports and Sweco
Safe Software
 
Cluster-Based Multi-Objective Metamorphic Test Case Pair Selection for Deep N...
Cluster-Based Multi-Objective Metamorphic Test Case Pair Selection for Deep N...
janeliewang985
 
Lessons Learned from Developing Secure AI Workflows.pdf
Lessons Learned from Developing Secure AI Workflows.pdf
Priyanka Aash
 
Information Security Response Team Nepal_npCERT_Vice_President_Sudan_Jha.pdf
Information Security Response Team Nepal_npCERT_Vice_President_Sudan_Jha.pdf
ICT Frame Magazine Pvt. Ltd.
 
FIDO Seminar: Targeting Trust: The Future of Identity in the Workforce.pptx
FIDO Seminar: Targeting Trust: The Future of Identity in the Workforce.pptx
FIDO Alliance
 
Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
 
Techniques for Automatic Device Identification and Network Assignment.pdf
Techniques for Automatic Device Identification and Network Assignment.pdf
Priyanka Aash
 
FIDO Seminar: Evolving Landscape of Post-Quantum Cryptography.pptx
FIDO Seminar: Evolving Landscape of Post-Quantum Cryptography.pptx
FIDO Alliance
 
PyCon SG 25 - Firecracker Made Easy with Python.pdf
PyCon SG 25 - Firecracker Made Easy with Python.pdf
Muhammad Yuga Nugraha
 
Connecting Data and Intelligence: The Role of FME in Machine Learning
Connecting Data and Intelligence: The Role of FME in Machine Learning
Safe Software
 
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
Python Conference Singapore - 19 Jun 2025
Python Conference Singapore - 19 Jun 2025
ninefyi
 
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
Priyanka Aash
 
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
 
Cyber Defense Matrix Workshop - RSA Conference
Cyber Defense Matrix Workshop - RSA Conference
Priyanka Aash
 
Creating Inclusive Digital Learning with AI: A Smarter, Fairer Future
Creating Inclusive Digital Learning with AI: A Smarter, Fairer Future
Impelsys Inc.
 
MuleSoft for AgentForce : Topic Center and API Catalog
MuleSoft for AgentForce : Topic Center and API Catalog
shyamraj55
 
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance
 
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Alliance
 
Wenn alles versagt - IBM Tape schützt, was zählt! Und besonders mit dem neust...
Wenn alles versagt - IBM Tape schützt, was zählt! Und besonders mit dem neust...
Josef Weingand
 
Smarter Aviation Data Management: Lessons from Swedavia Airports and Sweco
Smarter Aviation Data Management: Lessons from Swedavia Airports and Sweco
Safe Software
 
Cluster-Based Multi-Objective Metamorphic Test Case Pair Selection for Deep N...
Cluster-Based Multi-Objective Metamorphic Test Case Pair Selection for Deep N...
janeliewang985
 
Lessons Learned from Developing Secure AI Workflows.pdf
Lessons Learned from Developing Secure AI Workflows.pdf
Priyanka Aash
 
Information Security Response Team Nepal_npCERT_Vice_President_Sudan_Jha.pdf
Information Security Response Team Nepal_npCERT_Vice_President_Sudan_Jha.pdf
ICT Frame Magazine Pvt. Ltd.
 
FIDO Seminar: Targeting Trust: The Future of Identity in the Workforce.pptx
FIDO Seminar: Targeting Trust: The Future of Identity in the Workforce.pptx
FIDO Alliance
 
Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
 
Techniques for Automatic Device Identification and Network Assignment.pdf
Techniques for Automatic Device Identification and Network Assignment.pdf
Priyanka Aash
 
FIDO Seminar: Evolving Landscape of Post-Quantum Cryptography.pptx
FIDO Seminar: Evolving Landscape of Post-Quantum Cryptography.pptx
FIDO Alliance
 
PyCon SG 25 - Firecracker Made Easy with Python.pdf
PyCon SG 25 - Firecracker Made Easy with Python.pdf
Muhammad Yuga Nugraha
 
Connecting Data and Intelligence: The Role of FME in Machine Learning
Connecting Data and Intelligence: The Role of FME in Machine Learning
Safe Software
 
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
Python Conference Singapore - 19 Jun 2025
Python Conference Singapore - 19 Jun 2025
ninefyi
 
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
GenAI Opportunities and Challenges - Where 370 Enterprises Are Focusing Now.pdf
Priyanka Aash
 
AI vs Human Writing: Can You Tell the Difference?
AI vs Human Writing: Can You Tell the Difference?
Shashi Sathyanarayana, Ph.D
 
Cyber Defense Matrix Workshop - RSA Conference
Cyber Defense Matrix Workshop - RSA Conference
Priyanka Aash
 
Creating Inclusive Digital Learning with AI: A Smarter, Fairer Future
Creating Inclusive Digital Learning with AI: A Smarter, Fairer Future
Impelsys Inc.
 

Practical Ruby Projects with MongoDB - Ruby Midwest

  • 1. PRACTICAL PROJECTS WITH Saturday, July 17, 2010
  • 2. WHO AM I? Alex Sharp Lead Developer at OptimisDev @ajsharp (on the twitters) alexjsharp.com (on the ‘tubes) github.com/ajsharp (on the ‘hubs) Saturday, July 17, 2010
  • 3. MAJOR POINTS • Brief intro to MongoDB • Practical Projects • Making the case for Mongo (time permitting) Saturday, July 17, 2010
  • 5. WHAT IS MONGODB? mongodb is a high-performance, schema-less, document-oriented database Saturday, July 17, 2010
  • 8. SCHEMA-LESS • Great for rapid, iterative, agile development Saturday, July 17, 2010
  • 9. 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 Saturday, July 17, 2010
  • 11. DOCUMENT-ORIENTED • Mongo stores documents, not rows • documents are stored as binary json Saturday, July 17, 2010
  • 12. DOCUMENT-ORIENTED • Mongo stores documents, not rows • documents are stored as binary json • Allows for a rich query syntax Saturday, July 17, 2010
  • 13. DOCUMENT-ORIENTED • Mongo stores documents, not rows • documents are stored as binary json • Allows for a rich query syntax • Embedded documents eliminate many modeling headaches Saturday, July 17, 2010
  • 15. BIG DATA • Built to scale horizontally into the cloudz Saturday, July 17, 2010
  • 16. BIG DATA • Built to scale horizontally into the cloudz • Auto-sharding • set a shard-key, a cluster of nodes, go • still in alpha, but production-ready soon Saturday, July 17, 2010
  • 18. FAST WRITES • Mongo writes are “fire-and-forget” • you can get a response with getLastError() Saturday, July 17, 2010
  • 19. FAST WRITES • Mongo writes are “fire-and-forget” • you can get a response with getLastError() • In-place updates Saturday, July 17, 2010
  • 20. FAST WRITES • Mongo writes are “fire-and-forget” • you can get a response with getLastError() • In-place updates • Lot’s of db commands for fast updates Saturday, July 17, 2010
  • 21. AGGREGATION Map/reduce for aggregation Saturday, July 17, 2010
  • 22. READS FAST TOO Optimize reads with indexes, just like an rdbms Saturday, July 17, 2010
  • 24. JOINS nope. Saturday, July 17, 2010
  • 25. MULTI-DOCUMENT TRANSACTIONS no-sir-ee. Saturday, July 17, 2010
  • 26. RELATIONAL INTEGRITY not a chance. Saturday, July 17, 2010
  • 27. PRACTICAL PROJECTS Saturday, July 17, 2010
  • 28. 1. Accounting Application 2. Capped Collection Logging 3. Blogging app 4. Reporting app Saturday, July 17, 2010
  • 29. GENERAL LEDGER ACCOUNTING APPLICATION Saturday, July 17, 2010
  • 30. THE OBJECT MODEL ledger * transactions * entries Saturday, July 17, 2010
  • 31. 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 } Saturday, July 17, 2010
  • 32. THE OBJECT MODEL Saturday, July 17, 2010
  • 33. THE OBJECT MODEL • Each ledger line item belongs to a ledger Saturday, July 17, 2010
  • 34. THE OBJECT MODEL • Each ledger line item belongs to a ledger • Each ledger line item has two ledger entries • must have at least one credit and one debit • credits and debits must balance Saturday, July 17, 2010
  • 35. THE OBJECT MODEL • Each ledger line item belongs to a ledger • Each ledger line item has two ledger entries • must have at least one credit and one debit • credits and debits must balance • These objects must be transactional Saturday, July 17, 2010
  • 36. 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] Saturday, July 17, 2010
  • 37. 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 SQL schema, we need a database transaction to ensure multi-row atomicity Saturday, July 17, 2010
  • 38. 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] Remember: we have to create 3 new records in the database here Saturday, July 17, 2010
  • 39. MONGO-FIED MODELING @line_item = LineItem.new(:ledger_id => 1, :entries => [ {:account => 'Cash', :type => 'debit', :amount => 100}, {:account => 'Notes pay.', :type => 'debit', :amount => 100} ] ) Saturday, July 17, 2010
  • 40. 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. Saturday, July 17, 2010
  • 41. 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) Saturday, July 17, 2010
  • 42. 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 Saturday, July 17, 2010
  • 43. 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. Saturday, July 17, 2010
  • 45. LESSONS • Simplified, de-normalized data model • Objects modeled differently in Mongo than SQL Saturday, July 17, 2010
  • 46. LESSONS • Simplified, de-normalized data model • Objects modeled differently in Mongo than SQL • Simpler data model + no transactions = WIN Saturday, July 17, 2010
  • 47. LOGGING WITH CAPPED COLLECTIONS Saturday, July 17, 2010
  • 48. BASELESS STATISTIC 95% of the time logs are NEVER used. Saturday, July 17, 2010
  • 49. MOST LOGS ARE ONLY USED WHEN SOMETHING GOES WRONG Saturday, July 17, 2010
  • 50. CAPPED COLLECTIONS • Fixed-sized, limitedoperation, auto age-out collections (kinda like memcached, except persistent) • Fixed insertion order • Super fast (faster than normal writes) • Ideal for logging and caching Saturday, July 17, 2010
  • 51. GREAT. WHAT’S THAT MEAN? We can log additional pieces of arbitrary data effortlessly due to Mongo’s schemaless nature. Saturday, July 17, 2010
  • 52. THIS IS AWESOME Saturday, July 17, 2010
  • 54. ALSO A REALLY HANDY TROUBLESHOOTING TOOL Saturday, July 17, 2010
  • 55. User-reported errors are difficult to diagnose Saturday, July 17, 2010
  • 56. Wouldn’t it be useful to see the complete click- path? Saturday, July 17, 2010
  • 57. BUNYAN http://github.com/ajsharp/bunyan Thin ruby layer around a MongoDB capped collection Saturday, July 17, 2010
  • 58. BUNYAN http://github.com/ajsharp/bunyan Still needs a middleware api. Want to contribute? Saturday, July 17, 2010
  • 59. require 'bunyan' Bunyan::Logger.configure do |c| c.database 'my_bunyan_db' c.collection "#{Rails.env}_bunyan_log" c.size 1073741824 # 1.gigabyte end Saturday, July 17, 2010
  • 60. PAPERMILL http://github.com/ajsharp/papermill SINATRA FRONT-END TO BUNYAN Saturday, July 17, 2010
  • 61. BLOGGING APPLICATION Saturday, July 17, 2010
  • 62. BLOGGING APPLICATION Much easier to model with Mongo than a relational database Saturday, July 17, 2010
  • 63. BLOGGING APPLICATION A post has an author Saturday, July 17, 2010
  • 64. BLOGGING APPLICATION A post has an author A post has many tags Saturday, July 17, 2010
  • 65. BLOGGING APPLICATION A post has an author A post has many tags A post has many comments Saturday, July 17, 2010
  • 66. 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. Saturday, July 17, 2010
  • 68. MONGOMAPPER •MongoDB “ORM” developed by John Nunemaker Saturday, July 17, 2010
  • 69. MONGOMAPPER •MongoDB “ORM” developed by John Nunemaker •Very similar syntax to DataMapper Saturday, July 17, 2010
  • 70. MONGOMAPPER •MongoDB “ORM” developed by John Nunemaker •Very similar syntax to DataMapper •Declarative rather than inheritance-based Saturday, July 17, 2010
  • 71. MONGOMAPPER •MongoDB “ORM” developed by John Nunemaker •Very similar syntax to DataMapper •Declarative rather than inheritance-based •Very easy to drop into rails Saturday, July 17, 2010
  • 72. MONGOMAPPER require 'mongo' connection = Mongo::Connection.new.db("#{Rails.env}_app") class Post include MongoMapper::Document belongs_to :author, :class_name => "User" key :title, String, :reuqired => 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 Saturday, July 17, 2010
  • 75. REPORTING IS HARD • Synchronization • Data, application API, schema • Schema synchronization is the hard one Saturday, July 17, 2010
  • 76. WHY MONGO? • Aggregation support with Mongo’s map/reduce support • Mongo is good (and getting better) at handling big data sets • Schemaless is perfect for a flattened data set Saturday, July 17, 2010
  • 77. Amazon EC2 Rackspace Transform MongoDB Server Reporting App WAN Main App MySQL Saturday, July 17, 2010
  • 78. CLIENT REQUESTS Amazon EC2 MongoDB Server map/reduce Reporting App User requests Client request GET /reports/some_report Saturday, July 17, 2010
  • 79. TRANFORMATION Data needs to extracted from the the main app, transormed (i.e. flattened) into some other form, and loaded into the reporting app for aggregation Saturday, July 17, 2010
  • 80. TRANSFORMATION Rackspace Amazon EC2 1. GET /object_dependencies Transform MongoDB Server { :visit => [ :insurances, :patients ] } 2. read from active record MySQL 2. write to mongo Reporting App Main App Saturday, July 17, 2010
  • 81. MAKING THE CASE Saturday, July 17, 2010
  • 82. THE PROBLEMS OF SQL Saturday, July 17, 2010
  • 83. A BRIEF HISTORY OF SQL • Developed at IBM in early 1970’s. • Designed to manipulate and retrieve data stored in relational databases Saturday, July 17, 2010
  • 84. 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 Saturday, July 17, 2010
  • 86. WE DON’T WORK WITH DATA... Saturday, July 17, 2010
  • 87. WE WORK WITH OBJECTS Saturday, July 17, 2010
  • 88. WE DON’T CARE ABOUT STORING DATA Saturday, July 17, 2010
  • 89. WE CARE ABOUT PERSISTING STATE Saturday, July 17, 2010
  • 90. DATA != OBJECTS Saturday, July 17, 2010
  • 92. RELATIONAL DBS ARE AN ANTIQUATED TOOL FOR OUR NEEDS Saturday, July 17, 2010
  • 93. OK, SO WHAT? SQL schemas are designed for storing and querying data, not persisting objects. Saturday, July 17, 2010
  • 94. To reconcile this mismatch, we have ORM’s Saturday, July 17, 2010
  • 95. Object Relational Mappers Saturday, July 17, 2010
  • 96. OK, SO WHAT? We need ORMs to bridge the gap (map) between our native Ruby object model and a SQL schema Saturday, July 17, 2010
  • 97. We’re forced to create relationships for data when what we really want is properties for our objects. Saturday, July 17, 2010
  • 98. THIS IS NOT EFFICIENT Saturday, July 17, 2010
  • 99. @alex = Person.new( :name => "alex", :stalkings => [ Friend.new("Jim"), Friend.new("Bob")] ) Saturday, July 17, 2010
  • 100. Native ruby object <Person:0x10017d030 @name="alex", @stalkings= [#<Friend:0x10017d0a8 @name="Jim">, #<Friend:0x10017d058 @name="Bob"> ]> Saturday, July 17, 2010
  • 101. JSON/Mongo Representation @alex.to_json { name: "alex", stalkings: [{ name: "Jim" }, { name: "Bob" }] } Saturday, July 17, 2010
  • 102. SQL Schema Representation people: - name stalkings: - name - stalker_id Saturday, July 17, 2010
  • 103. SQL Schema Representation people: - name stalkings: What!? - name - stalker_id Saturday, July 17, 2010
  • 104. SQL Schema Representation people: - name stalkings: what’s a stalker_id? - name - stalker_id Saturday, July 17, 2010
  • 105. SQL Schema Representation people: - name stalkings: this is our sql mapping - name - stalker_id Saturday, July 17, 2010
  • 106. SQL Schema Representation people: - name stalkings: this is the - name “pointless” join - stalker_id Saturday, July 17, 2010
  • 107. 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 Saturday, July 17, 2010
  • 108. 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 having SQL stalkings: to work too hard here - name - stalker_id Saturday, July 17, 2010
  • 109. You’re probably thinking... “Listen GUY, SQL isn’t that bad” Saturday, July 17, 2010
  • 111. But we can do much, much better. Saturday, July 17, 2010
  • 112. NEEDS FOR A PERSISTENCE LAYER: Saturday, July 17, 2010
  • 113. NEEDS FOR A PERSISTENCE LAYER: 1. To persist the native state of our objects Saturday, July 17, 2010
  • 114. NEEDS FOR A PERSISTENCE LAYER: 1. To persist the native state of our objects 2. Should NOT interfere w/ application development Saturday, July 17, 2010
  • 115. NEEDS FOR A PERSISTENCE LAYER: 1. To persist the native state of our objects 2. Should NOT interfere w/ application development 3. Provides features necessary to build modern web apps Saturday, July 17, 2010
  • 117. USING MONGO W/ RUBY • Ruby mongo driver • MongoMapper (github.com/jnunemaker/mongomapper) • MongoID (github.com/durran/mongoid) • Many other ORM/ODM’s • mongo-sequel (github.com/jeremyevans/sequel-mongo) • moneta (github.com/wycats/moneta) Saturday, July 17, 2010
  • 118. MONGOMAPPER • DataMapper-like API • good for moving from a sql schema to mongo • easy to drop into rails • works with rails 3 Saturday, July 17, 2010
  • 119. MONGOID • DataMapper-like API • uses ActiveModel, so familiar validation syntax • more opinionated embedded docs • easy to drop into rails • rails 2 - mongoid 1.x • rails 3 - mongoid 2.x Saturday, July 17, 2010