MongoDB
(from “humongous”)




     Wouter de Vos – 2011-10-31
What is MongoDB?

•   A No-SQL database

•   Document oriented

•   Open Source

•   Written in C++
Document Oriented?

•   Documents are stored in collections   > db.posts.findOne()
                                          {
                                            _id : ObjectId("4e77bb3b8a3e000000004f7a"),
                                            when : Date("2011-09-19T02:10:11.3Z",
                                            author : "alex",


•
                                            title : "No Free Lunch",
    No JOINS: embedded                      text : "This is the text of the post. It could be very long.",
                                            tags : [ "business", "ramblings" ],
                                            votes : 5,
                                            voters : [ "jane", "joe", "spencer", "phyllis", "li" ],
                                            comments : [


•
                                              { who : "jane", when : Date("2011-09-19T04:00:10.112Z"),
    No JOINS: linked                            comment : "I agree." },
                                              { who : "meghan", when : Date("2011-09-20T14:36:06.958Z"),
                                                comment : "You must be joking. etc etc ..." }
                                            ]
                                          }
Document Oriented?

•   Documents are stored in collections   > db.posts.findOne()
                                          {
                                            _id : ObjectId("4e77bb3b8a3e000000004f7a"),
                                            when : Date("2011-09-19T02:10:11.3Z",
                                            author : "alex",


•
                                            title : "No Free Lunch",
    No JOINS: embedded                      text : "This is the text of the post. It could be very long.",
                                            tags : [ "business", "ramblings" ],
                                            votes : 5,
                                            voters : [ "jane", "joe", "spencer", "phyllis", "li" ],
                                            comments : [


•
                                              { who : "jane", when : Date("2011-09-19T04:00:10.112Z"),
    No JOINS: linked                            comment : "I agree." },
                                              { who : "meghan", when : Date("2011-09-20T14:36:06.958Z"),
                                                comment : "You must be joking. etc etc ..." }
                                            ]
                                          }
Document Oriented?

•   Documents are stored in collections
                                                      > db.posts.findOne()


•
                                                      {
    No JOINS: embedded                                  _id : ObjectId("4e77bb3b8a3e000000004f7a"),
                                                        when : Date("2011-09-19T02:10:11.3Z",
                                                        author : "alex",
                                                        title : "No Free Lunch",
                                                        text : "This is the text of the post. It could be very long.",


•
                                                        tags : [ "business", "ramblings" ],
    No JOINS: linked                                    votes : 5,
                                                        voters : [ "jane", "joe", "spencer", "phyllis", "li" ],
                                                        comments : [
                                                          { who : "jane", when : Date("2011-09-19T04:00:10.112Z"),
                                                            comment : "I agree." },


    •
                                                          { who : "meghan", when : Date("2011-09-20T14:36:06.958Z"),
        links are references to other documents and     ]
                                                            comment : "You must be joking. etc etc ..." }

        are processed by the client.                  }
Cool features
                                   > db.invoices.find()
                                   {

•   Schemaless
                                      _id : ObjectId("4e77bb3b8a3e000000004f7a"),
                                      client: "Johnson",
                                      hosting: {
                                         per: "month",


•
                                         price: 100,
    Atomic operations                 },
                                         amount: 12,

                                      development: {
                                         per: "hour",

•   Map/Reduce
                                      }
                                         price: 120,
                                         amount: 80

                                   },

•
                                   {
    Fast, in-place updates            _id : ObjectId("4e77bb3b8a3e000000005f7a"),
                                      client: "Black",
                                      development: {
                                         per: "hour",

•   GridFS
                                      }
                                         price: 120,
                                         amount: 30

                                   },
Cool features
•   Schemaless                     atomically {
                                     if( doc.credits > 5 ) {
                                       doc.credits -= 5;
•   Atomic operations                  doc.debits += 5;
                                     }
                                   }
•   Map/Reduce


•   Fast, in-place updates


•   GridFS
Cool features
                                 // Document example
                                 { username: "jones",
                                   likes: 20,
                                   text: "Hello world!"

•   Schemaless                   }

                                 // Map
                                 function() {

•   Atomic operations            }
                                   emit( this.username, {count: 1, likes: this.likes} );


                                 // Reduce

•
                                 function(key, values) {
    Map/Reduce                     var result = {count: 0, likes: 0};

                                     values.forEach(function(value) {
                                       result.count += value.count;

•   Fast, in-place updates             result.likes += value.likes;
                                     });

                                     return result;

•
                                 }
    GridFS
                                 // Result
                                 { count: 10, likes: 247 }
Cool features
•   Schemaless


•   Atomic operations
                               // In place update
                               db.recipes.update(

•   Map/Reduce
                               )
                                   {'_id': recipe_id, 'voters': {'$ne': user_id}},
                                   {'$inc': {'votes': 1}, '$push': {'voters': user_id}}




•   Fast, in-place updates


•   GridFS
Cool features
•   Schemaless


•   Atomic operations              The GridFS spec provides a mechanism for
                                transparently dividing a large le among multiple

•   Map/Reduce
                               documents. This allows us to efciently store large
                                objects, and in the case of especially large les,
                                 such as videos, permits range operations (e.g.,
•   Fast, in-place updates           fetching only the first N bytes of a file).


•   GridFS
Querying
• // A post with title “Mongo”
  db.posts.find({'title': 'Mongo'})


• // All posts about tennis, but without comments
  db.posts.find( { tags : 'tennis' }, { comments : 0 } );


• // last 5 comments
  db.posts.find({}, {comments:{'$slice': -5}})


• // just the likes of the comments
  db.posts.find({}, {'comments.$.likes': 1}
Use it for

•   It’s schemaless features (e.g. for prototyping)

•   It’s horizontal scalability (with auto-sharding)

•   To store and stream large files (with gridfs)

•   To make ultra-fast, single query updates
Cucumber
Scenarios for browser testing
Feature: User Registration and Logging in
  A User should be able to create an account.
  A User should be able to log in with a new account.
  A User should be able to create a prole after logging in for the rst time.

  Scenario: Registration with a normal account.
    Given I sign up as a new user with email@example.com/secret
    Then I should be signed in
    And I sign out

  Scenario: Log in with a new account
    Given I sign up as a new user with email@example.com/secret
    Then I should be signed in
    Then I sign out
    And I sign in with email@example.com/secret
    Then I should be signed in
    And I sign out

  Scenario: Create a prole with a new account
    Given I sign in as a new user
    Then I should see "create your prole"
    And I ll in "prole_name" with "My Name"
    And I ll in "prole_about" with "I am a long green vegetable that goes well with salads."
    And I select an avatar le
    And I press "Save"
    Then I should see "Prole was successfully updated."
    And I sign out
Step denitions in Ruby
Test Results
Mechanize, Selenium / Webkit


•   Mechanize: fast, but no javascript support

•   Selenium, javascript support, but sloooow

•   Webkit, javascript support, less slooow

Springest Dev Lunch: MongoDB Introduction

  • 1.
    MongoDB (from “humongous”) Wouter de Vos – 2011-10-31
  • 2.
    What is MongoDB? • A No-SQL database • Document oriented • Open Source • Written in C++
  • 3.
    Document Oriented? • Documents are stored in collections > db.posts.findOne() { _id : ObjectId("4e77bb3b8a3e000000004f7a"), when : Date("2011-09-19T02:10:11.3Z", author : "alex", • title : "No Free Lunch", No JOINS: embedded text : "This is the text of the post. It could be very long.", tags : [ "business", "ramblings" ], votes : 5, voters : [ "jane", "joe", "spencer", "phyllis", "li" ], comments : [ • { who : "jane", when : Date("2011-09-19T04:00:10.112Z"), No JOINS: linked comment : "I agree." }, { who : "meghan", when : Date("2011-09-20T14:36:06.958Z"), comment : "You must be joking. etc etc ..." } ] }
  • 4.
    Document Oriented? • Documents are stored in collections > db.posts.findOne() { _id : ObjectId("4e77bb3b8a3e000000004f7a"), when : Date("2011-09-19T02:10:11.3Z", author : "alex", • title : "No Free Lunch", No JOINS: embedded text : "This is the text of the post. It could be very long.", tags : [ "business", "ramblings" ], votes : 5, voters : [ "jane", "joe", "spencer", "phyllis", "li" ], comments : [ • { who : "jane", when : Date("2011-09-19T04:00:10.112Z"), No JOINS: linked comment : "I agree." }, { who : "meghan", when : Date("2011-09-20T14:36:06.958Z"), comment : "You must be joking. etc etc ..." } ] }
  • 5.
    Document Oriented? • Documents are stored in collections > db.posts.findOne() • { No JOINS: embedded _id : ObjectId("4e77bb3b8a3e000000004f7a"), when : Date("2011-09-19T02:10:11.3Z", author : "alex", title : "No Free Lunch", text : "This is the text of the post. It could be very long.", • tags : [ "business", "ramblings" ], No JOINS: linked votes : 5, voters : [ "jane", "joe", "spencer", "phyllis", "li" ], comments : [ { who : "jane", when : Date("2011-09-19T04:00:10.112Z"), comment : "I agree." }, • { who : "meghan", when : Date("2011-09-20T14:36:06.958Z"), links are references to other documents and ] comment : "You must be joking. etc etc ..." } are processed by the client. }
  • 6.
    Cool features > db.invoices.find() { • Schemaless _id : ObjectId("4e77bb3b8a3e000000004f7a"), client: "Johnson", hosting: { per: "month", • price: 100, Atomic operations }, amount: 12, development: { per: "hour", • Map/Reduce } price: 120, amount: 80 }, • { Fast, in-place updates _id : ObjectId("4e77bb3b8a3e000000005f7a"), client: "Black", development: { per: "hour", • GridFS } price: 120, amount: 30 },
  • 7.
    Cool features • Schemaless atomically { if( doc.credits > 5 ) { doc.credits -= 5; • Atomic operations doc.debits += 5; } } • Map/Reduce • Fast, in-place updates • GridFS
  • 8.
    Cool features // Document example { username: "jones", likes: 20, text: "Hello world!" • Schemaless } // Map function() { • Atomic operations } emit( this.username, {count: 1, likes: this.likes} ); // Reduce • function(key, values) { Map/Reduce var result = {count: 0, likes: 0}; values.forEach(function(value) { result.count += value.count; • Fast, in-place updates result.likes += value.likes; }); return result; • } GridFS // Result { count: 10, likes: 247 }
  • 9.
    Cool features • Schemaless • Atomic operations // In place update db.recipes.update( • Map/Reduce ) {'_id': recipe_id, 'voters': {'$ne': user_id}}, {'$inc': {'votes': 1}, '$push': {'voters': user_id}} • Fast, in-place updates • GridFS
  • 10.
    Cool features • Schemaless • Atomic operations The GridFS spec provides a mechanism for transparently dividing a large file among multiple • Map/Reduce documents. This allows us to efficiently store large objects, and in the case of especially large files, such as videos, permits range operations (e.g., • Fast, in-place updates fetching only the first N bytes of a file). • GridFS
  • 11.
    Querying • // Apost with title “Mongo” db.posts.find({'title': 'Mongo'}) • // All posts about tennis, but without comments db.posts.find( { tags : 'tennis' }, { comments : 0 } ); • // last 5 comments db.posts.find({}, {comments:{'$slice': -5}}) • // just the likes of the comments db.posts.find({}, {'comments.$.likes': 1}
  • 12.
    Use it for • It’s schemaless features (e.g. for prototyping) • It’s horizontal scalability (with auto-sharding) • To store and stream large files (with gridfs) • To make ultra-fast, single query updates
  • 13.
  • 14.
    Scenarios for browsertesting Feature: User Registration and Logging in A User should be able to create an account. A User should be able to log in with a new account. A User should be able to create a prole after logging in for the rst time. Scenario: Registration with a normal account. Given I sign up as a new user with email@example.com/secret Then I should be signed in And I sign out Scenario: Log in with a new account Given I sign up as a new user with email@example.com/secret Then I should be signed in Then I sign out And I sign in with email@example.com/secret Then I should be signed in And I sign out Scenario: Create a prole with a new account Given I sign in as a new user Then I should see "create your prole" And I ll in "prole_name" with "My Name" And I ll in "prole_about" with "I am a long green vegetable that goes well with salads." And I select an avatar le And I press "Save" Then I should see "Prole was successfully updated." And I sign out
  • 15.
  • 16.
  • 17.
    Mechanize, Selenium /Webkit • Mechanize: fast, but no javascript support • Selenium, javascript support, but sloooow • Webkit, javascript support, less slooow