SlideShare a Scribd company logo
1 of 143
Download to read offline
MongoDB
Today’s Agenda
MongoDB Intro
MongoDB Fundamentals
Running MongoDB
Building your first app
Deploying your first app to Heroku
@spf13

                  AKA
Steve Francia
15+ years building
the internet

  Father, husband,
  skateboarder



Chief Solutions Architect @
responsible for drivers,
integrations, web & docs
Company behind MongoDB

HQ in NYC & Palo Alto,
Offices in Sydney, London & Dublin

Support, consulting, training
Introduction
     to
MongoD
A bit of
history
1974
The relational database is created
OSCON 2012 MongoDB Tutorial
OSCON 2012 MongoDB Tutorial
1979
1979   1994
1979   1994   1995
Computers in 1995
100 mhz Pentium
10 base T
16 MB ram
200 MB HD
Cloud in 1995
(Windows 95 cloud wallpaper)
Cell Phones in
Quad core 1.4Ghz
802.11n (300+ Mbps)
2 GB ram
64 GB Solid State
The world is vastly
different than the
one the relational
  database was
    created for
What do we want in
 an ideal world?
What do we want in an
     ideal world?
What do we want in an
     ideal world?
•Horizontal scaling
  •cloud compatible
  •works with standard
 servers
What do we want in an
      ideal world?
•Horizontal scaling
  •cloud compatible
  •works with standard
  servers
•Fast
What do we want in an
     ideal world?
•Horizontal scaling
  •cloud compatible
  •works with standard
  servers
•Fast
•Easy Development
  •Features
  •The Right Data Model
  •Schema Agility
MongoDB philosophy
 Keep functionality when we can (key/value
 stores are great, but we need more)
 Non-relational (no joins) makes scaling
 horizontally practical
 Document data models are good
 Database technology should run anywhere
 virtualized, cloud, metal, etc
Under the hood
Written in C++
Runs nearly everywhere
Data serialized to BSON
Extensive use of memory-mapped files
i.e. read-through write-through
memory caching.
Database
Scalability & Performance


                            Memcached
                                             MongoDB



                                                   RDBMS


                                Depth of Functionality
“
MongoDB has the best
features of key/value
stores, document
databases and
relational databases
in one.
        John Nunemaker
Relational made normalized
     data look like this
                       Category
                   • Name
                   • Url




                            Article
        User       • Name
                                               Tag
 • Name            • Slug             • Name
 • Email Address   • Publish date     • Url
                   • Text




                      Comment
                   • Comment
                   • Date
                   • Author
Document databases make
normalized data look like this
                            Article
                     • Name
                     • Slug
                     • Publish date
        User         • Text
   • Name            • Author
   • Email Address
                         Comment[]
                      • Comment
                      • Date
                      • Author

                            Tag[]
                      • Value

                         Category[]
                      • Value
But we’ve been using
a relational database
    for 40 years!
How do people store
documents in real life?
Think about a
doctors office
 There’s two ways they
could organize their files
Each document type
        in it’s own drawer
MRIs    X-rays   Lab   Invoices       Index



          1      1        1       1




          1      1        1       1




   History Medications Lab    Forms
Each document type
        in it’s own drawer
MRIs    X-rays   Lab   Invoices       Index



          1      1        1       1




          1      1        1       1




   History Medications Lab    Forms
Each document type
        in it’s own drawer
MRIs    X-rays   Lab   Invoices       Index



          1      1        1       1




          1      1        1       1




   History Medications Lab    Forms
Group related records


   Patient 1   Patient 2   Patient 3   ...




   Vendor 1    Vendor 2    Vendor 3
Group related records


   Patient 1               Patient 3   ...


           Patient 2

   Vendor 1     Vendor 2   Vendor 3
Databases work the same way
          Relation                               Docum


                                         Patient 1     Vendor 1


                                                            Article
              Category                                 • Name
            • Name                                     • Slug
            • Url                                      • Publish
                                          User             date
                                                       •   Text
                                   •   Name            •   Author
                                   •   Email Address
               Article
    User                     Tag
            • Name                                         Comment[]
• Name                   • Name
• Email     • Slug       • Url                         • Comment
  Address   • Publish
               date                                    • Date
                                                       • Author

              Comment                                        Tag[]
            • Comment                                  • Value
            • Date
            • Author
                                                        Category[]
                                                       • Value
Terminology
 RDBMS                 Mongo
Table, View   ➜   Collection
Row           ➜   Document
Index         ➜   Index
Join          ➜   Embedded
Foreign Key   ➜   Document
                  Reference
Partition     ➜   Shard
MongoDB
Use Cases
CMS / Blog
Needs:
• Business needed modern data store for rapid development and
  scale

Solution:
• Use PHP & MongoDB

Results:
• Real time statistics
• All data, images, etc stored together
  easy access, easy deployment, easy high availability
• No need for complex migrations
• Enabled very rapid development and growth
Photo Meta-
Problem:
• Business needed more flexibility than Oracle could deliver

Solution:
• Use MongoDB instead of Oracle

Results:
• Developed application in one sprint cycle
• 500% cost reduction compared to Oracle
• 900% performance improvement compared to Oracle
Customer Analytics
Problem:
• Deal with massive data volume across all customer sites

Solution:
• Use MongoDB to replace Google Analytics / Omniture options

Results:
• Less than one week to build prototype and prove business case
• Rapid deployment of new features
Archiving
Why MongoDB:
• Existing application built on MySQL
• Lots of friction with RDBMS based archive storage
• Needed more scalable archive storage backend
Solution:
• Keep MySQL for active data (100mil)
• MongoDB for archive (2+ billion)
Results:
• No more alter table statements taking over 2 months to run
• Sharding fixed vertical scale problem
• Very happily looking at other places to use MongoDB
Online
Problem:
• MySQL could not scale to handle their 5B+ documents

Solution:
• Switched from MySQL to MongoDB

Results:
• Massive simplification of code base
• Eliminated need for external caching system
• 20x performance improvement over MySQL
E-commerce
Problem:
• Multi-vertical E-commerce impossible to model (efficiently) in
  RDBMS

Solution:
• Switched from MySQL to MongoDB

Results:
•   Massive simplification of code base
•   Rapidly build, halving time to market (and cost)
•   Eliminated need for external caching system
•   50x+ performance improvement over MySQL
Tons more
   MongoDB casts a wide net

  people keep coming up with
 new and brilliant ways to use it
In Good



 and 1000s more
MongoD
  B
Start with an
              (or array, hash, dict, e

place1 = {

   name : "10gen HQ",

 address : "578 Broadway 7th Floor",

   city : "New York",

    zip : "10011",
   tags : [ "business", "awesome" ]
}
Inserting the record
    Initial Data Load


               > db.places.insert(place1)

> db.places.insert(place1)
Querying
> db.places.findOne({ zip: "10011",
            tags: "awesome" })

> db.places.find({tags: "business" })

{

    name : "10gen HQ",

 address : "134 5th Avenue 3rd Floor",

    city : "New York",

     zip : "10011",
   tags : [ "business", "awesome" ]
}
Nested Documents
{ _id : ObjectId("4c4ba5c0672c685e5e8aabf3"),
   name : "10gen HQ",

 address : "578 Broadway 7th Floor",

   city : "New York",

    zip : "10011",
   tags : [ "business", "awesome" ],
    comments : [ {

        
 
 author : "Fred",

        
 
 date : "Sat Apr 25 2010 20:51:03",

        
 
 text : "Best Place Ever!"

     }]
}
Object ID
> db.places.insert(place1)

object(MongoId)#4 (1) {
  ["$id"]=> string(24) "4e9cc76a4a1817fd21000000"
}

   4e9cc76a4a1817fd21000000
   |------||----||--||----|
     ts  mac pid inc
Updating
> db.places.update(
  {name : "10gen HQ"},
  { $push :
     { comments :
        { author : "steve",
          date : 6/26/2012, 
          text : "Office hours are great!"
        }
     }
  }
)
Atomic

$set   $unset $rename
   $push $pop $pull
  $addToSet    $in
Index nested documents
// Index nested documents
> db.posts.ensureIndex({ "comments.author":1 })
> db.posts.find({'comments.author':'Fred'})

{      _id : ObjectId("4c4ba5c0672c685e5e8aabf3"),
      name : "10gen HQ",

   address : "578 Broadway 7th Floor",

     city : "New York",

      zip : "10011",
    comments : [ {

         
 
 author : "Fred",

         
 
 date : "Sat Apr 25 2010 20:51:03",

         
 
 text : "Best Place Ever!"

     }]
}
Regular Expressions
// Regular Expressions
> db.posts.find({'comments.author': /^Fr/})

{    _id : ObjectId("4c4ba5c0672c685e5e8aabf3"),
    name : "10gen HQ",

 address : "578 Broadway 7th Floor",

 city : "New York",

   zip : "10011",
  comments : [ {

       
 
 author : "Fred",

       
 
 date : "Sat Apr 25 2010 20:51:03",

       
 
 text : "Best Place Ever!"

 }]
}
Index multiple values
// Index on tags (multi-key index)
> db.posts.ensureIndex({ tags: 1})
> db.posts.find( { tags: 'tech' } )


{    _id : ObjectId("4c4ba5c0672c685e5e8aabf3"),
    name : "10gen HQ",

 address : "578 Broadway 7th Floor",

 city : "New York",

    zip : "10011",
    tags : [ "business", "awesome", "tech" ],
}
Geospatial
// geospatial index
> db.posts.ensureIndex({ "location": "2d" })
> db.posts.find({"location":{$near:[22,42]}})


{     _id : ObjectId("4c4ba5c0672c685e5e8aabf3"),
     name : "10gen HQ",

 address : "578 Broadway 7th Floor",

 city : "New York",

     zip : "10011",
  location : [ 22, 42 ],
}
Cursors
$cursor = $c->find(array("foo" => "bar"));

foreach ($cursor as $id => $value) {
   echo "$id: ";
   var_dump( $value );
}

$a = iterator_to_array($cursor);
Paging
page_num = 3;
results_per_page = 10;

cursor = db.collection.find()
  .sort({ "ts" : -1 })
  .skip((page_num - 1) * results_per_page)
  .limit(results_per_page);
Running
MongoDB
Fire up a
  mongo
mongo       mongod      mongoexport
mongoimport mongos       mongostat
mongo_console mongodump     mongofiles
mongorestore mongosniff   mongotop
Start Mongod
   mongod                          Note the d
mongod --help for help and startup options
Thu Jul 12 23:19:49 [initandlisten] MongoDB starting : pid=32237 port=27017 dbpath=/
data/db/ 64-bit host=Steves-MacBook-Air.local
Thu Jul 12 23:19:49 [initandlisten] db version v2.0.6, pdfile version 4.5
Thu Jul 12 23:19:49 [initandlisten] git version:
e1c0cbc25863f6356aa4e31375add7bb49fb05bc
Thu Jul 12 23:19:49 [initandlisten] build info: Darwin erh2.10gen.cc 9.8.0 Darwin Kernel
Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386
BOOST_LIB_VERSION=1_40
Thu Jul 12 23:19:49 [initandlisten] options: {}
Thu Jul 12 23:19:49 [initandlisten] journal dir=/data/db/journal
Thu Jul 12 23:19:49 [initandlisten] recover : no journal files present, no recovery needed
Thu Jul 12 23:19:49 [websvr] admin web console waiting for connections on port 28017
Thu Jul 12 23:19:49 [initandlisten] waiting for connections on port 27017
Download & Import the venues

      curl -L http://j.mp/OSCONvenues | 
   mongoimport -d milieu -c venues



                                      Database
                                                    Collection
wget http://c.spf13.com/OSCON/venuesImport.json
mongoimport -d milieu -c venues venuesImport.json
Start the Mongo shell
  mongo

> help
                        Note no d
db.help()           help on db methods
db.mycoll.help()       help on collection methods
rs.help()          help on replica set methods
help admin           administrative help
help connect          connecting to a db help
help keys           key shortcuts
help misc            misc things to know
help mr             mapreduce
show dbs              show database names
show collections        show collections in current database
show users           show users in current database
show profile          show most recent system.profile
Let’s look at the venues
> use milieu            Database
switched to db milieu

> db.venues.count()

50
Let’s look at the venues
> db.venues.findOne()

{ "_id" : ObjectId("4ff73cb568840767e50d4e9c"),
  "location" : {
    "address" : "777 NE ML King Blvd.",
    "cc" : "US",
    "city" : "Portland",
    "country" : "United States",
    "distance" : 18,
    "geo" : [ -122.66293287277222, 45.52829837051139 ],
    "postalCode" : "97232",
    "state" : "OR"
  },
"name" : "Agent Reboot Portland",
"stats" : {
  "checkinsCount" : 0,
  "usersCount" : 0
  }
}
Creating a Geo index
> db.venues.ensureIndex({ 'location.geo' : '2d'})
> db.venues.getIndexes()
[

    {

    
 "v" : 1,

    
 "key" : {

    
 
 "_id" : 1

    
 },

    
 "ns" : "milieu.venues",

    
 "name" : "_id_"

    },

    {

    
 "v" : 1,

    
 "key" : {

    
 
 "location.geo" : "2d"

    
 },

    
 "ns" : "milieu.venues",

       "name" : "location.geo_"

    }
]
Challenges
Create a new DB & Collection
Insert a new record into this collection
 ... with a nested field
Insert another record
Create an index (on a common field)
Query on the field and confirm index used
Update multiple records
Building a
MongoDB
   app
MongoDB Drivers
Official Support for 12 languages
Community drivers for tons more
Drivers connect to mongo servers
Drivers translate BSON into native types
mongo shell is not a driver, but works like
one in some ways
Building an app in
          Ruby?
Had to pick a language
Sinatra is very minimal and approachable
Wanted to focus on MongoDB interaction
Ruby gems are awesome
Works well on Windows, OS X & Linux
Seemed like a good idea at the time
A crash
course in
Sinatra &
  Ruby
1
st

     Ruby
Everything is an
        object
1.class      # => Fixnum
'a'.class    # => String
:z.class     # => Symbol

class Foo    # => Class
end

Foo.class     # => Foo
Foo.new.class
Structure
def do_stuff(thing)          Method
  thing.do_the_stuff
end

class TheThing               Class
  def do_the_stuff
    puts "Stuff was done!"
  end
end

do_stuff(TheThing.new)       Invocation
Strings
name = 'World'   # => "World"

"Hello, #{name}" # => "Hello, World"

'Hello, #{name}' # => "Hello, #{name}"
Numbers
1   + 1            #   =>   2
1   + 1.1          #   =>   2.1
6   * 7            #   =>   42
6   ** 7           #   =>   279936



Math.sqrt(65536)   #   =>   256.0
1.class            #   =>   Fixnum
(2 ** 42).class    #   =>   Fixnum
(2 ** 64).class    #   =>   Bignum
1.1.class          #   =>   Float
Arrays
Array.new      # => []
Array.new(3)   # => [nil, nil, nil]
[]             # => []

a = [1,2,3]    #   =>   [1, 2, 3]
a[0] = 'one'   #   =>   "one"
a              #   =>   ["one", 2, 3]
a[-1]          #   =>   3
a[1..2]        #   =>   [2, 3]
Hashes
Hash.new              # => {}
{}                    # => {}

h = {1 => "one", 2 => "two"}
h[1]                  # => "one"
h["1"]                # => nil
h[:one] = "einz"      # => "einz"
h[:one]               # => "einz"

h.keys                # => [1, 2, :one]
h.values              # => ["one", "two", "einz"]
Variables & Names
CamelCased         # Classes, modules
with_underscores   # methods, local variables
@instance_variable
@@class_variable
$GLOBAL_VARIABLE
Control Structures
   if condition
     # ...
   elsif other_condition
     # ...
   end
   unless condition
     # ...
   end
   while
   # ...
   end
OSCON 2012 MongoDB Tutorial
Sinatra is...
not Rails
not a framework
a DSL for quickly creating
web applications in Ruby
with minimal effort
Hello World
  # myapp.rb
require 'sinatra'

get '/' do
 'Hello world!'
end
HTTP Actions
   In Sinatra, a route is an HTTP method paired with a URL-matching pattern.
Each route is associated with a block:

get '/' do
 .. show something ..
end

post '/' do
 .. create something ..
end

put '/' do
 .. replace something ..
end

delete '/' do
 .. annihilate something ..
end
Routes
  Routes are matched in the order they are defined.
  The first route that matches the request is invoked.

Route patterns may include named parameters,
accessible via the params hash:

get '/hello/:name' do
 # matches "GET /hello/foo" and "GET /hello/bar"
 # params[:name] is 'foo' or 'bar'
 "Hello #{params[:name]}!"
end

#You can also access named parameters via block parameters:
get '/hello/:name' do |n|
 "Hello #{n}!"
end
Splat
  Route patterns may also include splat
  (or wildcard) parameters, accessible via the
  params[:splat] array:

get '/say/*/to/*' do
 # matches /say/hello/to/world
 params[:splat] # => ["hello", "world"]
end

get '/download/*.*' do
 # matches /download/path/to/file.xml
 params[:splat] # => ["path/to/file", "xml"]
end
Introducing the milieu app
Start with a skeleton
  /Users/steve/Code/milieu/app/     layout.haml*
▸ config/                           login.haml*
▸ helpers/                          navbar.haml*
▾ model/                            register.haml*
    mongodb.rb                      user_dashboard.haml*
     mongoModule.rb                 user_profile.haml*
    user.rb                         venue.haml*
▾ public/                           venues.haml*
  ▸ bootstrap/                    app.rb*
  ▾ css/                          config.ru*
      styles.css*                 Gemfile*
  ▸ images/                       Gemfile.lock*
▾ views/                          Rakefile*
    footer.haml*                  README*
    index.haml*
Download & Install deps
   mkdir milieu
   cd milieu
   wget http://c.spf13.com/OSCON/gettingStarted.tgz
   tar zxvf gettingStarted.tgz
   cd app
   bundle install
Using bson (1.6.4)
Using bson_ext (1.6.4)
Using googlestaticmap (1.1.3)
Using haml (3.1.4)
Using mongo (1.6.4)
Using rack (1.4.1)
Using rack-protection (1.2.0)
Using shotgun (0.9)
Using tilt (1.3.3)
Using sinatra (1.3.2)
Using bundler (1.1.4)
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
Run app
    shotgun
== Shotgun/WEBrick on http://127.0.0.1:9393/
[2012-07-14 11:37:34] INFO WEBrick 1.3.1
[2012-07-14 11:37:34] INFO ruby 1.9.3 (2012-04-20) [x86_64-
darwin11.4.0]
[2012-07-14 11:37:34] INFO WEBrick::HTTPServer#start: pid=42185
port=9393
Open Browser to localhost:
9393
Connecting to MongoDB
                                   model/mongodb.rb
require 'mongo'
require './model/mongoModule'
require './model/user'

CONNECTION   =   Mongo::Connection.new("localhost")
DB           =   CONNECTION.db('milieu')
USERS        =   DB['users']
VENUES       =   DB['venues']
CHECKINS     =   DB['checkins']
Listing Venues
                        app.rb


get '/venues' do
 @venues = VENUES.find
 haml :venues
end
Listing Venues
.container
  .content
                                                                     views/venues.haml
    %h2 Venues
    %table.table.table-striped
     %thead
      %tr
       %th Name
       %th Address
       %th Longitude
       %th Latitude

    %tbody
    ~@venues.each do |venue|
     %tr
      %td
       %a{:href => '/venue/' << venue['_id'].to_s}= venue['name']
      %td= venue['location']['address'] ? venue['location']['address'] : '&nbsp'
      %td= venue['location']['geo'][0].round(2)
      %td= venue['location']['geo'][1].round(2)
Listing Venues
         localhost:9393/venues
Paginating Venues
                                                app.rb

get '/venues/?:page?' do
 @page = params.fetch('page', 1).to_i
 pp = 10
 @venues = VENUES.find.skip(
    ( @page - 1 ) * pp).limit(pp)
 @total_pages = (VENUES.count.to_i / pp).ceil
 haml :venues
end
Listing Venues
         localhost:9393/venues
Creating Users
Users are a bit special in our app
Not just data
Special considerations for secure
password handling
Not complicated on MongoDB side, but
slightly complicated on Ruby side
Creating Users
class User                                                           model/user.rb
attr_accessor :_id, :name, :email, :email_hash, :salt, :hashed_password, :collection,
:updated_at

 def initialize
  self.collection = 'users'
 end

 def password=(pass)
  self.salt = random_string(10) unless self.salt
  self.hashed_password = User.encrypt(pass, self.salt)
 end

 def save
  col = DB[self.collection]
  self.updated_at = Time.now
  col.save(self.to_hash)
 end
end
Creating Users
post '/register'   do                                        app.rb
  u            =   User.new
  u.email      =   params[:email]
  u.password   =   params[:password]
  u.name       =   params[:name]

  if u.save()
    flash("User created")
    session[:user] = User.auth( params["email"], params["password"])
    redirect '/user/' << session[:user].email.to_s << "/dashboard"
  else
    tmp = []
    u.errors.each do |e|
       tmp << (e.join("<br/>"))
    end
    flash(tmp)
    redirect '/create'
  end
end
Logging in
configure do                       app.rb
 enable :sessions
end

before do
 unless session[:user] == nil
  @suser = session[:user]
 end
end

get '/user/:email/dashboard' do
 haml :user_dashboard
end
User Dashboard
.container                            views/user_dashboard.haml
  .content
    .page-header
      -unless @suser == nil?
       %h2="Dashboard"
       %br
       %image{src: "http://www.gravatar.com/avatar/" <<
@suser.email_hash.to_s << '.png'}

     %h3= @suser.name.to_s
    -else
     redirect '/'
    %small
     %a{href: "/user/" << @suser.email.to_s << "/profile"} profile
  .container#main-topic-nav
Dashboard
       localhost:9393/dashboard
Showing a Venue
                                              app.rb


get '/venue/:_id' do
 object_id =
   BSON::ObjectId.from_string(params[:_id])
 @venue = VENUES.find_one(
   { :_id => object_id })
 haml :venue
end
Showing a Venue
  .row-fluid                             views/venue.haml
    .span4
      %h2= @venue['name'].to_s
      %p
         =@venue['location']['address'].to_s
         %br= @venue['location']['city'].to_s +
       ' ' + @venue['location']['state'].to_s +
       ' ' + @venue['location']['postalCode'].to_s

    .span8
      %image{:src => '' << gmap_url(@venue, {:height =>
300, :width => 450}) }
A Venue   localhost:9393/venue/{id}
Nearby Venues
                                                  app.rb
get '/venue/:_id' do
 object_id =
   BSON::ObjectId.from_string(params[:_id])
 @venue = VENUES.find_one({ :_id => object_id })
 @nearby_venues = VENUES.find(
  { :'location.geo' =>
    { :$near => [ @venue['location']['geo'][0],
        @venue['location']['geo'][1]]
    }
  }).limit(4).skip(1)
 haml :venue
end
Listing Nearby Venues
...                                             views/venue.haml
  .row-fluid
  - @nearby_venues.each do |nearby|
   .span3
     %h2
       %a{:href => '/venue/' + nearby['_id'].to_s}=
nearby['name'].to_s
     %p
       =nearby['location']['address'].to_s
       %br= nearby['location']['city'].to_s +
     ' ' + nearby['location']['state'].to_s +
     ' ' + nearby['location']['postalCode'].to_s

      %a{:href => '/venue/' + nearby['_id'].to_s}
        %image{:src => '' << gmap_url(nearby, {:height =>
150, :width => 150, :zoom => 17}) }
Nearby Venues
        localhost:9393/venue/{id}
Checking in
                                                              app.rb
get '/venue/:_id/checkin' do
 object_id = BSON::ObjectId.from_string(params[:_id])
 @venue = VENUES.find_one({ :_id => object_id })
 user = USERS.find_and_modify(:query => { :_id => @suser._id},
    :update => {:$inc =>
        { "venues." << object_id.to_s => 1 } }, :new => 1)
 if user['venues'][params[:_id]] == 1
   VENUES.update({ :_id => @venue['_id']}, { :$inc =>
     { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}})
 else
   VENUES.update({ _id: @venue['_id']},
     { :$inc => { :'stats.checkinsCount' => 1}})
 end
 flash('Thanks for checking in')
 redirect '/venue/' + params[:_id]
end
Checking in
                                                              app.rb
get '/venue/:_id/checkin' do
 object_id = BSON::ObjectId.from_string(params[:_id])
 @venue = VENUES.find_one({ :_id => object_id })
 user = USERS.find_and_modify(:query => { :_id => @suser._id},
    :update => {:$inc =>
        { "venues." << object_id.to_s => 1 } }, :new => 1)
 if user['venues'][params[:_id]] == 1
   VENUES.update({ :_id => @venue['_id']}, { :$inc =>
     { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}})
 else
   VENUES.update({ _id: @venue['_id']},
     { :$inc => { :'stats.checkinsCount' => 1}})
 end
 flash('Thanks for checking in')
 redirect '/venue/' + params[:_id]
end
Checking in
                                                              app.rb
get '/venue/:_id/checkin' do
 object_id = BSON::ObjectId.from_string(params[:_id])
 @venue = VENUES.find_one({ :_id => object_id })
 user = USERS.find_and_modify(:query => { :_id => @suser._id},
    :update => {:$inc =>
        { "venues." << object_id.to_s => 1 } }, :new => 1)
 if user['venues'][params[:_id]] == 1
   VENUES.update({ :_id => @venue['_id']}, { :$inc =>
     { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}})
 else
   VENUES.update({ _id: @venue['_id']},
     { :$inc => { :'stats.checkinsCount' => 1}})
 end
 flash('Thanks for checking in')
 redirect '/venue/' + params[:_id]
end
Checking in
                                                              app.rb
get '/venue/:_id/checkin' do
 object_id = BSON::ObjectId.from_string(params[:_id])
 @venue = VENUES.find_one({ :_id => object_id })
 user = USERS.find_and_modify(:query => { :_id => @suser._id},
    :update => {:$inc =>
        { "venues." << object_id.to_s => 1 } }, :new => 1)
 if user['venues'][params[:_id]] == 1
   VENUES.update({ :_id => @venue['_id']}, { :$inc =>
     { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}})
 else
   VENUES.update({ _id: @venue['_id']},
     { :$inc => { :'stats.checkinsCount' => 1}})
 end
 flash('Thanks for checking in')
 redirect '/venue/' + params[:_id]
end
Checking in
                                                              app.rb
get '/venue/:_id/checkin' do
 object_id = BSON::ObjectId.from_string(params[:_id])
 @venue = VENUES.find_one({ :_id => object_id })
 user = USERS.find_and_modify(:query => { :_id => @suser._id},
    :update => {:$inc =>
        { "venues." << object_id.to_s => 1 } }, :new => 1)
 if user['venues'][params[:_id]] == 1
   VENUES.update({ :_id => @venue['_id']}, { :$inc =>
     { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}})
 else
   VENUES.update({ _id: @venue['_id']},
     { :$inc => { :'stats.checkinsCount' => 1}})
 end
 flash('Thanks for checking in')
 redirect '/venue/' + params[:_id]
end
Checking in
                                                              app.rb
get '/venue/:_id/checkin' do
 object_id = BSON::ObjectId.from_string(params[:_id])
 @venue = VENUES.find_one({ :_id => object_id })
 user = USERS.find_and_modify(:query => { :_id => @suser._id},
    :update => {:$inc =>
        { "venues." << object_id.to_s => 1 } }, :new => 1)
 if user['venues'][params[:_id]] == 1
   VENUES.update({ :_id => @venue['_id']}, { :$inc =>
     { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}})
 else
   VENUES.update({ _id: @venue['_id']},
     { :$inc => { :'stats.checkinsCount' => 1}})
 end
 flash('Thanks for checking in')
 redirect '/venue/' + params[:_id]
end
Checkin In
                                     views/venue.haml
%p
     %a.btn.btn-primary.btn-large{:href =>
       '/venue/' + @venue['_id'].to_s + '/checkin'}
        Check In Here
%p
  =@venue['stats']['usersCount'].ceil.to_s +
  ' users have checked in here ' +
  @venue['stats']['checkinsCount'].ceil.to_s +
  ' times'
%p=user_times_at
You’ve been here
 def user_times_at                              helpers/milieu.rb
  if logged_in?
      times = 'You have checked in here '
      if !@user.venues.nil? &&
         !@user.venues[params[:_id]].nil? times <<
          @user.venues[params[:_id]].to_s
      else
          times << '0'
      end
      times << ' times'
  else
      times = 'Please <a href='/login'>login</a> to join
them.'
  end
 end
A Venue   localhost:9393/venue/{id}
Deploying
to Heroku
Installing the Dependencies
  gem install heroku
Fetching: excon-0.14.3.gem (100%)
Fetching: heroku-api-0.2.8.gem (100%)
Fetching: netrc-0.7.5.gem (100%)
Fetching: mime-types-1.19.gem (100%)
Fetching: rest-client-1.6.7.gem (100%)
Fetching: launchy-2.1.0.gem (100%)
Fetching: rubyzip-0.9.9.gem (100%)
Fetching: heroku-2.28.12.gem (100%)
Successfully installed excon-0.14.3
Successfully installed heroku-api-0.2.8
Successfully installed netrc-0.7.5
Successfully installed mime-types-1.19
Successfully installed rest-client-1.6.7
Successfully installed launchy-2.1.0
Successfully installed rubyzip-0.9.9
Successfully installed heroku-2.28.12
8 gems installed
Signup for Heroku
Create app on Heroku
   heroku create app_name
Enter your Heroku credentials.
Email: Your_Email@Your_Domain.com
Password (typing will be hidden):
Found the following SSH public keys:
1) id_rsa.pub
Which would you like to use with your Heroku account? 1
Uploading SSH public key /Users/steve/.ssh/id_rsa.pub... done
Creating milieu... done, stack is cedar
http://milieu.herokuapp.com/ | git@heroku.com:milieu.git
Git remote heroku added
Pushing to Heroku
  git push heroku master
Warning: Permanently added the RSA host key for IP address '50.19.85.132' to the
list of known hosts.
Counting objects: 67, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (65/65), done.
Writing objects: 100% (67/67), 206.04 KiB, done.
Total 67 (delta 9), reused 0 (delta 0)

-----> Heroku receiving push
-----> Removing .DS_Store files
-----> Ruby/Rack app detected
-----> Installing dependencies using Bundler version 1.2.0.pre
    Running: bundle install --without development:test --path vendor/bundle --
binstubs bin/ --deployment
    Fetching gem metadata from http://rubygems.org/.......
    Installing bson (1.6.4)
    Installing bson_ext (1.6.4) with native extensions
    Installing googlestaticmap (1.1.3)
    Installing haml (3.1.4)
Fetching gem metadata from http://rubygems.org/.......


Pushing to Heroku
    Installing bson (1.6.4)
    Installing bson_ext (1.6.4) with native extensions
    Installing googlestaticmap (1.1.3)
    Installing haml (3.1.4)
    Installing mongo (1.6.4)
    Installing rack (1.4.1)
    Installing rack-protection (1.2.0)
    Installing shotgun (0.9)
    Installing tilt (1.3.3)
    Installing sinatra (1.3.2)
    Using bundler (1.2.0.pre)
    Your bundle is complete! It was installed into ./vendor/bundle
    Cleaning up the bundler cache.
-----> Writing config/database.yml to read from DATABASE_URL
-----> Discovering process types
    Procfile declares types     -> (none)
    Default types for Ruby/Rack -> console, rake, web
-----> Compiled slug size is 1.4MB
-----> Launching... done, v3
    http://milieu.herokuapp.com deployed to Heroku

To git@heroku.com:milieu.git
 * [new branch]  master -> master
Adding MongoHQ/Lab
  heroku addons:add mongohq
Adding mongohq to milieu... done, v4 (free)
Use `heroku addons:docs mongohq` to view documentation
Adjusting Connection
                                    model/mongodb.rb
if ENV['RACK_ENV'] == 'production'
  db = URI.parse(ENV['MONGOHQ_URL'])
  db_name = db.path.gsub(/^//, '')
  DB = Mongo::Connection.new(
     db.host, db.port).db(db_name)
  DB.authenticate(db.user, db.password) unless
    (db.user.nil? || db.user.nil?)
else
  DB = Mongo::Connection.new(
     "localhost", 27017).db('milieu')
end
Config MongoHQ/Lab
   heroku config
=== Config Vars for milieu
GEM_PATH: vendor/bundle/ruby/1.9.1
LANG:    en_US.UTF-8
MONGOHQ_URL: mongodb://heroku:3vw...xv12@staff.mongohq.com:100XX/
appXX
PATH:    bin:vendor/bundle/ruby/1.9.1/bin:/usr/local/bin:/usr/bin:/bin
RACK_ENV: production



                               Password                   Port


                   Username                  Server               DB
Connecting to the shell
mongo -u USER -p PASSWORD SERVER:PORT/DB_NAME
Importing the Venues
  mongoimport 
  -u heroku 
  -p PASSWORD 
  -h staff.mongohq.com 
 --port PORT 
  -d DB_NAME 
  -c venues 
venuesImport.json
Debugging
    heroku logs
2012-07-14T03:24:31+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/mongo-1.6.4/lib/mongo/
connection.rb:420:in `connect': Failed to connect to a master node at localhost:27017 (Mongo::ConnectionFailure)
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/vendor/bundle/ruby/1.9.1/gems/mongo-1.6.4/lib/
mongo/connection.rb:594:in `setup'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/vendor/bundle/ruby/1.9.1/gems/mongo-1.6.4/lib/
mongo/connection.rb:130:in `initialize'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/model/mongodb.rb:5:in `new'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/model/mongodb.rb:5:in `<top (required)>'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/app.rb:4:in `<top (required)>'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/config.ru:6:in `require'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/app.rb:4:in `require'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/config.ru:6:in `block in <main>'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/
builder.rb:51:in `instance_eval'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/
builder.rb:51:in `initialize'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/config.ru:1:in `new'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/
builder.rb:40:in `eval'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/config.ru:1:in `<main>'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/
builder.rb:40:in `parse_file'
2012-07-14T03:24:31+00:00 app[web.1]: 
 from /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/
server.rb:200:in `app'
Deploying new versions
   git push heroku
Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 424 bytes, done.
Total 4 (delta 2), reused 0 (delta 0)

-----> Heroku receiving push
-----> Removing .DS_Store files
-----> Ruby/Rack app detected
-----> Installing dependencies using Bundler version 1.2.0.pre
    Running: bundle install --without development:test --path vendor/bundle --
binstubs bin/ --deployment
    Using bson (1.6.4)
    Using bson_ext (1.6.4)
    Using googlestaticmap (1.1.3)
    Using haml (3.1.4)
    Using mongo (1.6.4)
    Using rack (1.4.1)
    Using rack-protection (1.2.0)
Using googlestaticmap (1.1.3)


Deploying new versions
    Using haml (3.1.4)
    Using mongo (1.6.4)
    Using rack (1.4.1)
    Using rack-protection (1.2.0)
    Using shotgun (0.9)
    Using tilt (1.3.3)
    Using sinatra (1.3.2)
    Using bundler (1.2.0.pre)
    Your bundle is complete! It was installed into ./vendor/bundle
    Cleaning up the bundler cache.
-----> Writing config/database.yml to read from DATABASE_URL
-----> Discovering process types
    Procfile declares types    -> (none)
    Default types for Ruby/Rack -> console, rake, web
-----> Compiled slug size is 1.4MB
-----> Launching... done, v6
    http://milieu.herokuapp.com deployed to Heroku

To git@heroku.com:milieu.git
  9d5d688..ad894be master -> master
Checkout your deployed app
Next ?
It’s all on
Programmin
     g
 Challenge
Some Ideas
‣Createdifferent
user levels          ‣Timestamped
(admin)              Checkins
‣Createinterface     ‣Amore complete
to add venues        dashboard with
                     stats
‣Connectto
foursquare           ‣Badgesor
                     Categories
‣Login   w/twitter
OSCON 2012 MongoDB Tutorial
One More Thing...
http://spf13.com
                           http://github.com/s
                           @spf13




Question
    download at mongodb.org
We’re hiring!! Contact us at jobs@10gen.com
OSCON 2012 MongoDB Tutorial

More Related Content

What's hot

MongoDB for Coder Training (Coding Serbia 2013)
MongoDB for Coder Training (Coding Serbia 2013)MongoDB for Coder Training (Coding Serbia 2013)
MongoDB for Coder Training (Coding Serbia 2013)Uwe Printz
 
An Introduction To NoSQL & MongoDB
An Introduction To NoSQL & MongoDBAn Introduction To NoSQL & MongoDB
An Introduction To NoSQL & MongoDBLee Theobald
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDBRavi Teja
 
Webinar: What's new in the .NET Driver
Webinar: What's new in the .NET DriverWebinar: What's new in the .NET Driver
Webinar: What's new in the .NET DriverMongoDB
 
A Presentation on MongoDB Introduction - Habilelabs
A Presentation on MongoDB Introduction - HabilelabsA Presentation on MongoDB Introduction - Habilelabs
A Presentation on MongoDB Introduction - HabilelabsHabilelabs
 
Intro To Mongo Db
Intro To Mongo DbIntro To Mongo Db
Intro To Mongo Dbchriskite
 
Conceptos básicos. seminario web 3 : Diseño de esquema pensado para documentos
Conceptos básicos. seminario web 3 : Diseño de esquema pensado para documentosConceptos básicos. seminario web 3 : Diseño de esquema pensado para documentos
Conceptos básicos. seminario web 3 : Diseño de esquema pensado para documentosMongoDB
 
MongoDB : The Definitive Guide
MongoDB : The Definitive GuideMongoDB : The Definitive Guide
MongoDB : The Definitive GuideWildan Maulana
 
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
 Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDBMongoDB
 
Introduction to mongo db
Introduction to mongo dbIntroduction to mongo db
Introduction to mongo dbRohit Bishnoi
 
Mongo DB: Fundamentals & Basics/ An Overview of MongoDB/ Mongo DB tutorials
Mongo DB: Fundamentals & Basics/ An Overview of MongoDB/ Mongo DB tutorialsMongo DB: Fundamentals & Basics/ An Overview of MongoDB/ Mongo DB tutorials
Mongo DB: Fundamentals & Basics/ An Overview of MongoDB/ Mongo DB tutorialsSpringPeople
 
Strengths and Weaknesses of MongoDB
Strengths and Weaknesses of MongoDBStrengths and Weaknesses of MongoDB
Strengths and Weaknesses of MongoDBlehresman
 
Basics of MongoDB
Basics of MongoDB Basics of MongoDB
Basics of MongoDB Habilelabs
 
MongoDB Pros and Cons
MongoDB Pros and ConsMongoDB Pros and Cons
MongoDB Pros and Consjohnrjenson
 

What's hot (20)

MongoDB for Coder Training (Coding Serbia 2013)
MongoDB for Coder Training (Coding Serbia 2013)MongoDB for Coder Training (Coding Serbia 2013)
MongoDB for Coder Training (Coding Serbia 2013)
 
An Introduction To NoSQL & MongoDB
An Introduction To NoSQL & MongoDBAn Introduction To NoSQL & MongoDB
An Introduction To NoSQL & MongoDB
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
Mongo DB
Mongo DB Mongo DB
Mongo DB
 
Webinar: What's new in the .NET Driver
Webinar: What's new in the .NET DriverWebinar: What's new in the .NET Driver
Webinar: What's new in the .NET Driver
 
A Presentation on MongoDB Introduction - Habilelabs
A Presentation on MongoDB Introduction - HabilelabsA Presentation on MongoDB Introduction - Habilelabs
A Presentation on MongoDB Introduction - Habilelabs
 
Intro To Mongo Db
Intro To Mongo DbIntro To Mongo Db
Intro To Mongo Db
 
Conceptos básicos. seminario web 3 : Diseño de esquema pensado para documentos
Conceptos básicos. seminario web 3 : Diseño de esquema pensado para documentosConceptos básicos. seminario web 3 : Diseño de esquema pensado para documentos
Conceptos básicos. seminario web 3 : Diseño de esquema pensado para documentos
 
MongoDB : The Definitive Guide
MongoDB : The Definitive GuideMongoDB : The Definitive Guide
MongoDB : The Definitive Guide
 
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
 Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
Conceptos básicos. Seminario web 2: Su primera aplicación MongoDB
 
MongoDB and Schema Design
MongoDB and Schema DesignMongoDB and Schema Design
MongoDB and Schema Design
 
Introduction to mongo db
Introduction to mongo dbIntroduction to mongo db
Introduction to mongo db
 
Mongo DB: Fundamentals & Basics/ An Overview of MongoDB/ Mongo DB tutorials
Mongo DB: Fundamentals & Basics/ An Overview of MongoDB/ Mongo DB tutorialsMongo DB: Fundamentals & Basics/ An Overview of MongoDB/ Mongo DB tutorials
Mongo DB: Fundamentals & Basics/ An Overview of MongoDB/ Mongo DB tutorials
 
MongoDB for Genealogy
MongoDB for GenealogyMongoDB for Genealogy
MongoDB for Genealogy
 
Strengths and Weaknesses of MongoDB
Strengths and Weaknesses of MongoDBStrengths and Weaknesses of MongoDB
Strengths and Weaknesses of MongoDB
 
MongoDB 101
MongoDB 101MongoDB 101
MongoDB 101
 
MongoDB
MongoDBMongoDB
MongoDB
 
Basics of MongoDB
Basics of MongoDB Basics of MongoDB
Basics of MongoDB
 
MongoDB Pros and Cons
MongoDB Pros and ConsMongoDB Pros and Cons
MongoDB Pros and Cons
 
Introduction to mongodb
Introduction to mongodbIntroduction to mongodb
Introduction to mongodb
 

Viewers also liked

Back to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB ApplicationBack to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB ApplicationMongoDB
 
Back to Basics Webinar 6: Production Deployment
Back to Basics Webinar 6: Production DeploymentBack to Basics Webinar 6: Production Deployment
Back to Basics Webinar 6: Production DeploymentMongoDB
 
Back to Basics Webinar 4: Advanced Indexing, Text and Geospatial Indexes
Back to Basics Webinar 4: Advanced Indexing, Text and Geospatial IndexesBack to Basics Webinar 4: Advanced Indexing, Text and Geospatial Indexes
Back to Basics Webinar 4: Advanced Indexing, Text and Geospatial IndexesMongoDB
 
Beyond the Basics 1: Storage Engines
Beyond the Basics 1: Storage EnginesBeyond the Basics 1: Storage Engines
Beyond the Basics 1: Storage EnginesMongoDB
 
Back to Basics Webinar 1: Introduction to NoSQL
Back to Basics Webinar 1: Introduction to NoSQLBack to Basics Webinar 1: Introduction to NoSQL
Back to Basics Webinar 1: Introduction to NoSQLMongoDB
 
Mongo db data-models guide
Mongo db data-models guideMongo db data-models guide
Mongo db data-models guideDeysi Gmarra
 
MongoDB Schema Design (Event: An Evening with MongoDB Houston 3/11/15)
MongoDB Schema Design (Event: An Evening with MongoDB Houston 3/11/15)MongoDB Schema Design (Event: An Evening with MongoDB Houston 3/11/15)
MongoDB Schema Design (Event: An Evening with MongoDB Houston 3/11/15)MongoDB
 
Back to Basics, webinar 4: Indicizzazione avanzata, indici testuali e geospaz...
Back to Basics, webinar 4: Indicizzazione avanzata, indici testuali e geospaz...Back to Basics, webinar 4: Indicizzazione avanzata, indici testuali e geospaz...
Back to Basics, webinar 4: Indicizzazione avanzata, indici testuali e geospaz...MongoDB
 
Back to Basics Webinar 5: Introduction to the Aggregation Framework
Back to Basics Webinar 5: Introduction to the Aggregation FrameworkBack to Basics Webinar 5: Introduction to the Aggregation Framework
Back to Basics Webinar 5: Introduction to the Aggregation FrameworkMongoDB
 
Back to Basics Webinar 3: Schema Design Thinking in Documents
 Back to Basics Webinar 3: Schema Design Thinking in Documents Back to Basics Webinar 3: Schema Design Thinking in Documents
Back to Basics Webinar 3: Schema Design Thinking in DocumentsMongoDB
 
Webinarserie: Einführung in MongoDB: “Back to Basics” - Teil 3 - Interaktion ...
Webinarserie: Einführung in MongoDB: “Back to Basics” - Teil 3 - Interaktion ...Webinarserie: Einführung in MongoDB: “Back to Basics” - Teil 3 - Interaktion ...
Webinarserie: Einführung in MongoDB: “Back to Basics” - Teil 3 - Interaktion ...MongoDB
 
Webinar: Getting Started with MongoDB - Back to Basics
Webinar: Getting Started with MongoDB - Back to BasicsWebinar: Getting Started with MongoDB - Back to Basics
Webinar: Getting Started with MongoDB - Back to BasicsMongoDB
 
Webinar: Back to Basics: Thinking in Documents
Webinar: Back to Basics: Thinking in DocumentsWebinar: Back to Basics: Thinking in Documents
Webinar: Back to Basics: Thinking in DocumentsMongoDB
 
Advanced Schema Design Patterns
Advanced Schema Design PatternsAdvanced Schema Design Patterns
Advanced Schema Design PatternsMongoDB
 
Back to Basics: My First MongoDB Application
Back to Basics: My First MongoDB ApplicationBack to Basics: My First MongoDB Application
Back to Basics: My First MongoDB ApplicationMongoDB
 
Developing with the Modern App Stack: MEAN and MERN (with Angular2 and ReactJS)
Developing with the Modern App Stack: MEAN and MERN (with Angular2 and ReactJS)Developing with the Modern App Stack: MEAN and MERN (with Angular2 and ReactJS)
Developing with the Modern App Stack: MEAN and MERN (with Angular2 and ReactJS)MongoDB
 

Viewers also liked (17)

Back to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB ApplicationBack to Basics Webinar 2: Your First MongoDB Application
Back to Basics Webinar 2: Your First MongoDB Application
 
Back to Basics Webinar 6: Production Deployment
Back to Basics Webinar 6: Production DeploymentBack to Basics Webinar 6: Production Deployment
Back to Basics Webinar 6: Production Deployment
 
Back to Basics Webinar 4: Advanced Indexing, Text and Geospatial Indexes
Back to Basics Webinar 4: Advanced Indexing, Text and Geospatial IndexesBack to Basics Webinar 4: Advanced Indexing, Text and Geospatial Indexes
Back to Basics Webinar 4: Advanced Indexing, Text and Geospatial Indexes
 
MongoDB for Developers
MongoDB for DevelopersMongoDB for Developers
MongoDB for Developers
 
Beyond the Basics 1: Storage Engines
Beyond the Basics 1: Storage EnginesBeyond the Basics 1: Storage Engines
Beyond the Basics 1: Storage Engines
 
Back to Basics Webinar 1: Introduction to NoSQL
Back to Basics Webinar 1: Introduction to NoSQLBack to Basics Webinar 1: Introduction to NoSQL
Back to Basics Webinar 1: Introduction to NoSQL
 
Mongo db data-models guide
Mongo db data-models guideMongo db data-models guide
Mongo db data-models guide
 
MongoDB Schema Design (Event: An Evening with MongoDB Houston 3/11/15)
MongoDB Schema Design (Event: An Evening with MongoDB Houston 3/11/15)MongoDB Schema Design (Event: An Evening with MongoDB Houston 3/11/15)
MongoDB Schema Design (Event: An Evening with MongoDB Houston 3/11/15)
 
Back to Basics, webinar 4: Indicizzazione avanzata, indici testuali e geospaz...
Back to Basics, webinar 4: Indicizzazione avanzata, indici testuali e geospaz...Back to Basics, webinar 4: Indicizzazione avanzata, indici testuali e geospaz...
Back to Basics, webinar 4: Indicizzazione avanzata, indici testuali e geospaz...
 
Back to Basics Webinar 5: Introduction to the Aggregation Framework
Back to Basics Webinar 5: Introduction to the Aggregation FrameworkBack to Basics Webinar 5: Introduction to the Aggregation Framework
Back to Basics Webinar 5: Introduction to the Aggregation Framework
 
Back to Basics Webinar 3: Schema Design Thinking in Documents
 Back to Basics Webinar 3: Schema Design Thinking in Documents Back to Basics Webinar 3: Schema Design Thinking in Documents
Back to Basics Webinar 3: Schema Design Thinking in Documents
 
Webinarserie: Einführung in MongoDB: “Back to Basics” - Teil 3 - Interaktion ...
Webinarserie: Einführung in MongoDB: “Back to Basics” - Teil 3 - Interaktion ...Webinarserie: Einführung in MongoDB: “Back to Basics” - Teil 3 - Interaktion ...
Webinarserie: Einführung in MongoDB: “Back to Basics” - Teil 3 - Interaktion ...
 
Webinar: Getting Started with MongoDB - Back to Basics
Webinar: Getting Started with MongoDB - Back to BasicsWebinar: Getting Started with MongoDB - Back to Basics
Webinar: Getting Started with MongoDB - Back to Basics
 
Webinar: Back to Basics: Thinking in Documents
Webinar: Back to Basics: Thinking in DocumentsWebinar: Back to Basics: Thinking in Documents
Webinar: Back to Basics: Thinking in Documents
 
Advanced Schema Design Patterns
Advanced Schema Design PatternsAdvanced Schema Design Patterns
Advanced Schema Design Patterns
 
Back to Basics: My First MongoDB Application
Back to Basics: My First MongoDB ApplicationBack to Basics: My First MongoDB Application
Back to Basics: My First MongoDB Application
 
Developing with the Modern App Stack: MEAN and MERN (with Angular2 and ReactJS)
Developing with the Modern App Stack: MEAN and MERN (with Angular2 and ReactJS)Developing with the Modern App Stack: MEAN and MERN (with Angular2 and ReactJS)
Developing with the Modern App Stack: MEAN and MERN (with Angular2 and ReactJS)
 

Similar to OSCON 2012 MongoDB Tutorial

Schema Design by Example ~ MongoSF 2012
Schema Design by Example ~ MongoSF 2012Schema Design by Example ~ MongoSF 2012
Schema Design by Example ~ MongoSF 2012hungarianhc
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDBSean Laurent
 
SDEC2011 NoSQL concepts and models
SDEC2011 NoSQL concepts and modelsSDEC2011 NoSQL concepts and models
SDEC2011 NoSQL concepts and modelsKorea Sdec
 
Mongo db eveningschemadesign
Mongo db eveningschemadesignMongo db eveningschemadesign
Mongo db eveningschemadesignMongoDB APAC
 
NoSQL databases and managing big data
NoSQL databases and managing big dataNoSQL databases and managing big data
NoSQL databases and managing big dataSteven Francia
 
10gen MongoDB Video Presentation at WebGeek DevCup
10gen MongoDB Video Presentation at WebGeek DevCup10gen MongoDB Video Presentation at WebGeek DevCup
10gen MongoDB Video Presentation at WebGeek DevCupWebGeek Philippines
 
MongoDB Introduction talk at Dr Dobbs Conference, MongoDB Evenings at Bangalo...
MongoDB Introduction talk at Dr Dobbs Conference, MongoDB Evenings at Bangalo...MongoDB Introduction talk at Dr Dobbs Conference, MongoDB Evenings at Bangalo...
MongoDB Introduction talk at Dr Dobbs Conference, MongoDB Evenings at Bangalo...Prasoon Kumar
 
The Fine Art of Schema Design in MongoDB: Dos and Don'ts
The Fine Art of Schema Design in MongoDB: Dos and Don'tsThe Fine Art of Schema Design in MongoDB: Dos and Don'ts
The Fine Art of Schema Design in MongoDB: Dos and Don'tsMatias Cascallares
 
MongoDB NYC Python
MongoDB NYC PythonMongoDB NYC Python
MongoDB NYC PythonMike Dirolf
 
No SQL : Which way to go? Presented at DDDMelbourne 2015
No SQL : Which way to go?  Presented at DDDMelbourne 2015No SQL : Which way to go?  Presented at DDDMelbourne 2015
No SQL : Which way to go? Presented at DDDMelbourne 2015Himanshu Desai
 
MongoDB by Emroz sardar.
MongoDB by Emroz sardar.MongoDB by Emroz sardar.
MongoDB by Emroz sardar.Emroz Sardar
 
Webinar: Building Your First Application with MongoDB
Webinar: Building Your First Application with MongoDBWebinar: Building Your First Application with MongoDB
Webinar: Building Your First Application with MongoDBMongoDB
 
Scaling with MongoDB
Scaling with MongoDBScaling with MongoDB
Scaling with MongoDBMongoDB
 
Building your first app with mongo db
Building your first app with mongo dbBuilding your first app with mongo db
Building your first app with mongo dbMongoDB
 
Managing Social Content with MongoDB
Managing Social Content with MongoDBManaging Social Content with MongoDB
Managing Social Content with MongoDBMongoDB
 
MongoDB EuroPython 2009
MongoDB EuroPython 2009MongoDB EuroPython 2009
MongoDB EuroPython 2009Mike Dirolf
 

Similar to OSCON 2012 MongoDB Tutorial (20)

MongoDB Basics
MongoDB BasicsMongoDB Basics
MongoDB Basics
 
Schema Design by Example ~ MongoSF 2012
Schema Design by Example ~ MongoSF 2012Schema Design by Example ~ MongoSF 2012
Schema Design by Example ~ MongoSF 2012
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
SDEC2011 NoSQL concepts and models
SDEC2011 NoSQL concepts and modelsSDEC2011 NoSQL concepts and models
SDEC2011 NoSQL concepts and models
 
Mongo db eveningschemadesign
Mongo db eveningschemadesignMongo db eveningschemadesign
Mongo db eveningschemadesign
 
NoSQL databases and managing big data
NoSQL databases and managing big dataNoSQL databases and managing big data
NoSQL databases and managing big data
 
10gen MongoDB Video Presentation at WebGeek DevCup
10gen MongoDB Video Presentation at WebGeek DevCup10gen MongoDB Video Presentation at WebGeek DevCup
10gen MongoDB Video Presentation at WebGeek DevCup
 
MongoDB Introduction talk at Dr Dobbs Conference, MongoDB Evenings at Bangalo...
MongoDB Introduction talk at Dr Dobbs Conference, MongoDB Evenings at Bangalo...MongoDB Introduction talk at Dr Dobbs Conference, MongoDB Evenings at Bangalo...
MongoDB Introduction talk at Dr Dobbs Conference, MongoDB Evenings at Bangalo...
 
The Fine Art of Schema Design in MongoDB: Dos and Don'ts
The Fine Art of Schema Design in MongoDB: Dos and Don'tsThe Fine Art of Schema Design in MongoDB: Dos and Don'ts
The Fine Art of Schema Design in MongoDB: Dos and Don'ts
 
MongoDB
MongoDBMongoDB
MongoDB
 
MongoDB NYC Python
MongoDB NYC PythonMongoDB NYC Python
MongoDB NYC Python
 
No SQL : Which way to go? Presented at DDDMelbourne 2015
No SQL : Which way to go?  Presented at DDDMelbourne 2015No SQL : Which way to go?  Presented at DDDMelbourne 2015
No SQL : Which way to go? Presented at DDDMelbourne 2015
 
NoSQL, which way to go?
NoSQL, which way to go?NoSQL, which way to go?
NoSQL, which way to go?
 
MongoDB by Emroz sardar.
MongoDB by Emroz sardar.MongoDB by Emroz sardar.
MongoDB by Emroz sardar.
 
mongoDB at Visibiz
mongoDB at VisibizmongoDB at Visibiz
mongoDB at Visibiz
 
Webinar: Building Your First Application with MongoDB
Webinar: Building Your First Application with MongoDBWebinar: Building Your First Application with MongoDB
Webinar: Building Your First Application with MongoDB
 
Scaling with MongoDB
Scaling with MongoDBScaling with MongoDB
Scaling with MongoDB
 
Building your first app with mongo db
Building your first app with mongo dbBuilding your first app with mongo db
Building your first app with mongo db
 
Managing Social Content with MongoDB
Managing Social Content with MongoDBManaging Social Content with MongoDB
Managing Social Content with MongoDB
 
MongoDB EuroPython 2009
MongoDB EuroPython 2009MongoDB EuroPython 2009
MongoDB EuroPython 2009
 

More from Steven Francia

State of the Gopher Nation - Golang - August 2017
State of the Gopher Nation - Golang - August 2017State of the Gopher Nation - Golang - August 2017
State of the Gopher Nation - Golang - August 2017Steven Francia
 
Building Awesome CLI apps in Go
Building Awesome CLI apps in GoBuilding Awesome CLI apps in Go
Building Awesome CLI apps in GoSteven Francia
 
The Future of the Operating System - Keynote LinuxCon 2015
The Future of the Operating System -  Keynote LinuxCon 2015The Future of the Operating System -  Keynote LinuxCon 2015
The Future of the Operating System - Keynote LinuxCon 2015Steven Francia
 
7 Common Mistakes in Go (2015)
7 Common Mistakes in Go (2015)7 Common Mistakes in Go (2015)
7 Common Mistakes in Go (2015)Steven Francia
 
What every successful open source project needs
What every successful open source project needsWhat every successful open source project needs
What every successful open source project needsSteven Francia
 
7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid them7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid themSteven Francia
 
Go for Object Oriented Programmers or Object Oriented Programming without Obj...
Go for Object Oriented Programmers or Object Oriented Programming without Obj...Go for Object Oriented Programmers or Object Oriented Programming without Obj...
Go for Object Oriented Programmers or Object Oriented Programming without Obj...Steven Francia
 
Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go Steven Francia
 
Getting Started with Go
Getting Started with GoGetting Started with Go
Getting Started with GoSteven Francia
 
Build your first MongoDB App in Ruby @ StrangeLoop 2013
Build your first MongoDB App in Ruby @ StrangeLoop 2013Build your first MongoDB App in Ruby @ StrangeLoop 2013
Build your first MongoDB App in Ruby @ StrangeLoop 2013Steven Francia
 
Modern Database Systems (for Genealogy)
Modern Database Systems (for Genealogy)Modern Database Systems (for Genealogy)
Modern Database Systems (for Genealogy)Steven Francia
 
Introduction to MongoDB and Hadoop
Introduction to MongoDB and HadoopIntroduction to MongoDB and Hadoop
Introduction to MongoDB and HadoopSteven Francia
 
MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012Steven Francia
 
Big data for the rest of us
Big data for the rest of usBig data for the rest of us
Big data for the rest of usSteven Francia
 
Replication, Durability, and Disaster Recovery
Replication, Durability, and Disaster RecoveryReplication, Durability, and Disaster Recovery
Replication, Durability, and Disaster RecoverySteven Francia
 
Multi Data Center Strategies
Multi Data Center StrategiesMulti Data Center Strategies
Multi Data Center StrategiesSteven Francia
 
MongoDB, Hadoop and Humongous Data
MongoDB, Hadoop and Humongous DataMongoDB, Hadoop and Humongous Data
MongoDB, Hadoop and Humongous DataSteven Francia
 
Hybrid MongoDB and RDBMS Applications
Hybrid MongoDB and RDBMS ApplicationsHybrid MongoDB and RDBMS Applications
Hybrid MongoDB and RDBMS ApplicationsSteven Francia
 
Building your first application w/mongoDB MongoSV2011
Building your first application w/mongoDB MongoSV2011Building your first application w/mongoDB MongoSV2011
Building your first application w/mongoDB MongoSV2011Steven Francia
 

More from Steven Francia (20)

State of the Gopher Nation - Golang - August 2017
State of the Gopher Nation - Golang - August 2017State of the Gopher Nation - Golang - August 2017
State of the Gopher Nation - Golang - August 2017
 
Building Awesome CLI apps in Go
Building Awesome CLI apps in GoBuilding Awesome CLI apps in Go
Building Awesome CLI apps in Go
 
The Future of the Operating System - Keynote LinuxCon 2015
The Future of the Operating System -  Keynote LinuxCon 2015The Future of the Operating System -  Keynote LinuxCon 2015
The Future of the Operating System - Keynote LinuxCon 2015
 
7 Common Mistakes in Go (2015)
7 Common Mistakes in Go (2015)7 Common Mistakes in Go (2015)
7 Common Mistakes in Go (2015)
 
What every successful open source project needs
What every successful open source project needsWhat every successful open source project needs
What every successful open source project needs
 
7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid them7 Common mistakes in Go and when to avoid them
7 Common mistakes in Go and when to avoid them
 
Go for Object Oriented Programmers or Object Oriented Programming without Obj...
Go for Object Oriented Programmers or Object Oriented Programming without Obj...Go for Object Oriented Programmers or Object Oriented Programming without Obj...
Go for Object Oriented Programmers or Object Oriented Programming without Obj...
 
Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go Painless Data Storage with MongoDB & Go
Painless Data Storage with MongoDB & Go
 
Getting Started with Go
Getting Started with GoGetting Started with Go
Getting Started with Go
 
Build your first MongoDB App in Ruby @ StrangeLoop 2013
Build your first MongoDB App in Ruby @ StrangeLoop 2013Build your first MongoDB App in Ruby @ StrangeLoop 2013
Build your first MongoDB App in Ruby @ StrangeLoop 2013
 
Modern Database Systems (for Genealogy)
Modern Database Systems (for Genealogy)Modern Database Systems (for Genealogy)
Modern Database Systems (for Genealogy)
 
Introduction to MongoDB and Hadoop
Introduction to MongoDB and HadoopIntroduction to MongoDB and Hadoop
Introduction to MongoDB and Hadoop
 
Future of data
Future of dataFuture of data
Future of data
 
MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012MongoDB, Hadoop and humongous data - MongoSV 2012
MongoDB, Hadoop and humongous data - MongoSV 2012
 
Big data for the rest of us
Big data for the rest of usBig data for the rest of us
Big data for the rest of us
 
Replication, Durability, and Disaster Recovery
Replication, Durability, and Disaster RecoveryReplication, Durability, and Disaster Recovery
Replication, Durability, and Disaster Recovery
 
Multi Data Center Strategies
Multi Data Center StrategiesMulti Data Center Strategies
Multi Data Center Strategies
 
MongoDB, Hadoop and Humongous Data
MongoDB, Hadoop and Humongous DataMongoDB, Hadoop and Humongous Data
MongoDB, Hadoop and Humongous Data
 
Hybrid MongoDB and RDBMS Applications
Hybrid MongoDB and RDBMS ApplicationsHybrid MongoDB and RDBMS Applications
Hybrid MongoDB and RDBMS Applications
 
Building your first application w/mongoDB MongoSV2011
Building your first application w/mongoDB MongoSV2011Building your first application w/mongoDB MongoSV2011
Building your first application w/mongoDB MongoSV2011
 

Recently uploaded

Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 
Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.francesco barbera
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaborationbruanjhuli
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostMatt Ray
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6DianaGray10
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024D Cloud Solutions
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfinfogdgmi
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
Do we need a new standard for visualizing the invisible?
Do we need a new standard for visualizing the invisible?Do we need a new standard for visualizing the invisible?
Do we need a new standard for visualizing the invisible?SANGHEE SHIN
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8DianaGray10
 
GenAI and AI GCC State of AI_Object Automation Inc
GenAI and AI GCC State of AI_Object Automation IncGenAI and AI GCC State of AI_Object Automation Inc
GenAI and AI GCC State of AI_Object Automation IncObject Automation
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfDaniel Santiago Silva Capera
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 

Recently uploaded (20)

Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 
Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.Digital magic. A small project for controlling smart light bulbs.
Digital magic. A small project for controlling smart light bulbs.
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
 
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCostKubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
KubeConEU24-Monitoring Kubernetes and Cloud Spend with OpenCost
 
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6UiPath Studio Web workshop series - Day 6
UiPath Studio Web workshop series - Day 6
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdf
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
Do we need a new standard for visualizing the invisible?
Do we need a new standard for visualizing the invisible?Do we need a new standard for visualizing the invisible?
Do we need a new standard for visualizing the invisible?
 
UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8UiPath Studio Web workshop series - Day 8
UiPath Studio Web workshop series - Day 8
 
GenAI and AI GCC State of AI_Object Automation Inc
GenAI and AI GCC State of AI_Object Automation IncGenAI and AI GCC State of AI_Object Automation Inc
GenAI and AI GCC State of AI_Object Automation Inc
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdfIaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
IaC & GitOps in a Nutshell - a FridayInANuthshell Episode.pdf
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 

OSCON 2012 MongoDB Tutorial

  • 2. Today’s Agenda MongoDB Intro MongoDB Fundamentals Running MongoDB Building your first app Deploying your first app to Heroku
  • 3. @spf13 AKA Steve Francia 15+ years building the internet Father, husband, skateboarder Chief Solutions Architect @ responsible for drivers, integrations, web & docs
  • 4. Company behind MongoDB HQ in NYC & Palo Alto, Offices in Sydney, London & Dublin Support, consulting, training
  • 5. Introduction to MongoD
  • 10. 1979
  • 11. 1979 1994
  • 12. 1979 1994 1995
  • 13. Computers in 1995 100 mhz Pentium 10 base T 16 MB ram 200 MB HD
  • 14. Cloud in 1995 (Windows 95 cloud wallpaper)
  • 15. Cell Phones in Quad core 1.4Ghz 802.11n (300+ Mbps) 2 GB ram 64 GB Solid State
  • 16. The world is vastly different than the one the relational database was created for
  • 17. What do we want in an ideal world?
  • 18. What do we want in an ideal world?
  • 19. What do we want in an ideal world? •Horizontal scaling •cloud compatible •works with standard servers
  • 20. What do we want in an ideal world? •Horizontal scaling •cloud compatible •works with standard servers •Fast
  • 21. What do we want in an ideal world? •Horizontal scaling •cloud compatible •works with standard servers •Fast •Easy Development •Features •The Right Data Model •Schema Agility
  • 22. MongoDB philosophy Keep functionality when we can (key/value stores are great, but we need more) Non-relational (no joins) makes scaling horizontally practical Document data models are good Database technology should run anywhere virtualized, cloud, metal, etc
  • 23. Under the hood Written in C++ Runs nearly everywhere Data serialized to BSON Extensive use of memory-mapped files i.e. read-through write-through memory caching.
  • 24. Database Scalability & Performance Memcached MongoDB RDBMS Depth of Functionality
  • 25. “ MongoDB has the best features of key/value stores, document databases and relational databases in one. John Nunemaker
  • 26. Relational made normalized data look like this Category • Name • Url Article User • Name Tag • Name • Slug • Name • Email Address • Publish date • Url • Text Comment • Comment • Date • Author
  • 27. Document databases make normalized data look like this Article • Name • Slug • Publish date User • Text • Name • Author • Email Address Comment[] • Comment • Date • Author Tag[] • Value Category[] • Value
  • 28. But we’ve been using a relational database for 40 years!
  • 29. How do people store documents in real life?
  • 30. Think about a doctors office There’s two ways they could organize their files
  • 31. Each document type in it’s own drawer MRIs X-rays Lab Invoices Index 1 1 1 1 1 1 1 1 History Medications Lab Forms
  • 32. Each document type in it’s own drawer MRIs X-rays Lab Invoices Index 1 1 1 1 1 1 1 1 History Medications Lab Forms
  • 33. Each document type in it’s own drawer MRIs X-rays Lab Invoices Index 1 1 1 1 1 1 1 1 History Medications Lab Forms
  • 34. Group related records Patient 1 Patient 2 Patient 3 ... Vendor 1 Vendor 2 Vendor 3
  • 35. Group related records Patient 1 Patient 3 ... Patient 2 Vendor 1 Vendor 2 Vendor 3
  • 36. Databases work the same way Relation Docum Patient 1 Vendor 1 Article Category • Name • Name • Slug • Url • Publish User date • Text • Name • Author • Email Address Article User Tag • Name Comment[] • Name • Name • Email • Slug • Url • Comment Address • Publish date • Date • Author Comment Tag[] • Comment • Value • Date • Author Category[] • Value
  • 37. Terminology RDBMS Mongo Table, View ➜ Collection Row ➜ Document Index ➜ Index Join ➜ Embedded Foreign Key ➜ Document Reference Partition ➜ Shard
  • 39. CMS / Blog Needs: • Business needed modern data store for rapid development and scale Solution: • Use PHP & MongoDB Results: • Real time statistics • All data, images, etc stored together easy access, easy deployment, easy high availability • No need for complex migrations • Enabled very rapid development and growth
  • 40. Photo Meta- Problem: • Business needed more flexibility than Oracle could deliver Solution: • Use MongoDB instead of Oracle Results: • Developed application in one sprint cycle • 500% cost reduction compared to Oracle • 900% performance improvement compared to Oracle
  • 41. Customer Analytics Problem: • Deal with massive data volume across all customer sites Solution: • Use MongoDB to replace Google Analytics / Omniture options Results: • Less than one week to build prototype and prove business case • Rapid deployment of new features
  • 42. Archiving Why MongoDB: • Existing application built on MySQL • Lots of friction with RDBMS based archive storage • Needed more scalable archive storage backend Solution: • Keep MySQL for active data (100mil) • MongoDB for archive (2+ billion) Results: • No more alter table statements taking over 2 months to run • Sharding fixed vertical scale problem • Very happily looking at other places to use MongoDB
  • 43. Online Problem: • MySQL could not scale to handle their 5B+ documents Solution: • Switched from MySQL to MongoDB Results: • Massive simplification of code base • Eliminated need for external caching system • 20x performance improvement over MySQL
  • 44. E-commerce Problem: • Multi-vertical E-commerce impossible to model (efficiently) in RDBMS Solution: • Switched from MySQL to MongoDB Results: • Massive simplification of code base • Rapidly build, halving time to market (and cost) • Eliminated need for external caching system • 50x+ performance improvement over MySQL
  • 45. Tons more MongoDB casts a wide net people keep coming up with new and brilliant ways to use it
  • 46. In Good and 1000s more
  • 48. Start with an (or array, hash, dict, e place1 = { name : "10gen HQ", address : "578 Broadway 7th Floor", city : "New York", zip : "10011", tags : [ "business", "awesome" ] }
  • 49. Inserting the record Initial Data Load > db.places.insert(place1) > db.places.insert(place1)
  • 50. Querying > db.places.findOne({ zip: "10011", tags: "awesome" }) > db.places.find({tags: "business" }) { name : "10gen HQ", address : "134 5th Avenue 3rd Floor", city : "New York", zip : "10011", tags : [ "business", "awesome" ] }
  • 51. Nested Documents { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), name : "10gen HQ", address : "578 Broadway 7th Floor", city : "New York", zip : "10011", tags : [ "business", "awesome" ], comments : [ { author : "Fred", date : "Sat Apr 25 2010 20:51:03", text : "Best Place Ever!" }] }
  • 52. Object ID > db.places.insert(place1) object(MongoId)#4 (1) { ["$id"]=> string(24) "4e9cc76a4a1817fd21000000" } 4e9cc76a4a1817fd21000000 |------||----||--||----| ts mac pid inc
  • 53. Updating > db.places.update( {name : "10gen HQ"}, { $push : { comments : { author : "steve", date : 6/26/2012, text : "Office hours are great!" } } } )
  • 54. Atomic $set $unset $rename $push $pop $pull $addToSet $in
  • 55. Index nested documents // Index nested documents > db.posts.ensureIndex({ "comments.author":1 }) > db.posts.find({'comments.author':'Fred'}) { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), name : "10gen HQ", address : "578 Broadway 7th Floor", city : "New York", zip : "10011", comments : [ { author : "Fred", date : "Sat Apr 25 2010 20:51:03", text : "Best Place Ever!" }] }
  • 56. Regular Expressions // Regular Expressions > db.posts.find({'comments.author': /^Fr/}) { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), name : "10gen HQ", address : "578 Broadway 7th Floor", city : "New York", zip : "10011", comments : [ { author : "Fred", date : "Sat Apr 25 2010 20:51:03", text : "Best Place Ever!" }] }
  • 57. Index multiple values // Index on tags (multi-key index) > db.posts.ensureIndex({ tags: 1}) > db.posts.find( { tags: 'tech' } ) { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), name : "10gen HQ", address : "578 Broadway 7th Floor", city : "New York", zip : "10011", tags : [ "business", "awesome", "tech" ], }
  • 58. Geospatial // geospatial index > db.posts.ensureIndex({ "location": "2d" }) > db.posts.find({"location":{$near:[22,42]}}) { _id : ObjectId("4c4ba5c0672c685e5e8aabf3"), name : "10gen HQ", address : "578 Broadway 7th Floor", city : "New York", zip : "10011", location : [ 22, 42 ], }
  • 59. Cursors $cursor = $c->find(array("foo" => "bar")); foreach ($cursor as $id => $value) { echo "$id: "; var_dump( $value ); } $a = iterator_to_array($cursor);
  • 60. Paging page_num = 3; results_per_page = 10; cursor = db.collection.find() .sort({ "ts" : -1 }) .skip((page_num - 1) * results_per_page) .limit(results_per_page);
  • 62. Fire up a mongo mongo mongod mongoexport mongoimport mongos mongostat mongo_console mongodump mongofiles mongorestore mongosniff mongotop
  • 63. Start Mongod mongod Note the d mongod --help for help and startup options Thu Jul 12 23:19:49 [initandlisten] MongoDB starting : pid=32237 port=27017 dbpath=/ data/db/ 64-bit host=Steves-MacBook-Air.local Thu Jul 12 23:19:49 [initandlisten] db version v2.0.6, pdfile version 4.5 Thu Jul 12 23:19:49 [initandlisten] git version: e1c0cbc25863f6356aa4e31375add7bb49fb05bc Thu Jul 12 23:19:49 [initandlisten] build info: Darwin erh2.10gen.cc 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386 BOOST_LIB_VERSION=1_40 Thu Jul 12 23:19:49 [initandlisten] options: {} Thu Jul 12 23:19:49 [initandlisten] journal dir=/data/db/journal Thu Jul 12 23:19:49 [initandlisten] recover : no journal files present, no recovery needed Thu Jul 12 23:19:49 [websvr] admin web console waiting for connections on port 28017 Thu Jul 12 23:19:49 [initandlisten] waiting for connections on port 27017
  • 64. Download & Import the venues curl -L http://j.mp/OSCONvenues | mongoimport -d milieu -c venues Database Collection wget http://c.spf13.com/OSCON/venuesImport.json mongoimport -d milieu -c venues venuesImport.json
  • 65. Start the Mongo shell mongo > help Note no d db.help() help on db methods db.mycoll.help() help on collection methods rs.help() help on replica set methods help admin administrative help help connect connecting to a db help help keys key shortcuts help misc misc things to know help mr mapreduce show dbs show database names show collections show collections in current database show users show users in current database show profile show most recent system.profile
  • 66. Let’s look at the venues > use milieu Database switched to db milieu > db.venues.count() 50
  • 67. Let’s look at the venues > db.venues.findOne() { "_id" : ObjectId("4ff73cb568840767e50d4e9c"), "location" : { "address" : "777 NE ML King Blvd.", "cc" : "US", "city" : "Portland", "country" : "United States", "distance" : 18, "geo" : [ -122.66293287277222, 45.52829837051139 ], "postalCode" : "97232", "state" : "OR" }, "name" : "Agent Reboot Portland", "stats" : { "checkinsCount" : 0, "usersCount" : 0 } }
  • 68. Creating a Geo index > db.venues.ensureIndex({ 'location.geo' : '2d'}) > db.venues.getIndexes() [ { "v" : 1, "key" : { "_id" : 1 }, "ns" : "milieu.venues", "name" : "_id_" }, { "v" : 1, "key" : { "location.geo" : "2d" }, "ns" : "milieu.venues", "name" : "location.geo_" } ]
  • 69. Challenges Create a new DB & Collection Insert a new record into this collection ... with a nested field Insert another record Create an index (on a common field) Query on the field and confirm index used Update multiple records
  • 71. MongoDB Drivers Official Support for 12 languages Community drivers for tons more Drivers connect to mongo servers Drivers translate BSON into native types mongo shell is not a driver, but works like one in some ways
  • 72. Building an app in Ruby? Had to pick a language Sinatra is very minimal and approachable Wanted to focus on MongoDB interaction Ruby gems are awesome Works well on Windows, OS X & Linux Seemed like a good idea at the time
  • 74. 1 st Ruby
  • 75. Everything is an object 1.class # => Fixnum 'a'.class # => String :z.class # => Symbol class Foo # => Class end Foo.class # => Foo Foo.new.class
  • 76. Structure def do_stuff(thing) Method thing.do_the_stuff end class TheThing Class def do_the_stuff puts "Stuff was done!" end end do_stuff(TheThing.new) Invocation
  • 77. Strings name = 'World' # => "World" "Hello, #{name}" # => "Hello, World" 'Hello, #{name}' # => "Hello, #{name}"
  • 78. Numbers 1 + 1 # => 2 1 + 1.1 # => 2.1 6 * 7 # => 42 6 ** 7 # => 279936 Math.sqrt(65536) # => 256.0 1.class # => Fixnum (2 ** 42).class # => Fixnum (2 ** 64).class # => Bignum 1.1.class # => Float
  • 79. Arrays Array.new # => [] Array.new(3) # => [nil, nil, nil] [] # => [] a = [1,2,3] # => [1, 2, 3] a[0] = 'one' # => "one" a # => ["one", 2, 3] a[-1] # => 3 a[1..2] # => [2, 3]
  • 80. Hashes Hash.new # => {} {} # => {} h = {1 => "one", 2 => "two"} h[1] # => "one" h["1"] # => nil h[:one] = "einz" # => "einz" h[:one] # => "einz" h.keys # => [1, 2, :one] h.values # => ["one", "two", "einz"]
  • 81. Variables & Names CamelCased # Classes, modules with_underscores # methods, local variables @instance_variable @@class_variable $GLOBAL_VARIABLE
  • 82. Control Structures if condition # ... elsif other_condition # ... end unless condition # ... end while # ... end
  • 84. Sinatra is... not Rails not a framework a DSL for quickly creating web applications in Ruby with minimal effort
  • 85. Hello World # myapp.rb require 'sinatra' get '/' do 'Hello world!' end
  • 86. HTTP Actions In Sinatra, a route is an HTTP method paired with a URL-matching pattern. Each route is associated with a block: get '/' do .. show something .. end post '/' do .. create something .. end put '/' do .. replace something .. end delete '/' do .. annihilate something .. end
  • 87. Routes Routes are matched in the order they are defined. The first route that matches the request is invoked. Route patterns may include named parameters, accessible via the params hash: get '/hello/:name' do # matches "GET /hello/foo" and "GET /hello/bar" # params[:name] is 'foo' or 'bar' "Hello #{params[:name]}!" end #You can also access named parameters via block parameters: get '/hello/:name' do |n| "Hello #{n}!" end
  • 88. Splat Route patterns may also include splat (or wildcard) parameters, accessible via the params[:splat] array: get '/say/*/to/*' do # matches /say/hello/to/world params[:splat] # => ["hello", "world"] end get '/download/*.*' do # matches /download/path/to/file.xml params[:splat] # => ["path/to/file", "xml"] end
  • 90. Start with a skeleton /Users/steve/Code/milieu/app/ layout.haml* ▸ config/ login.haml* ▸ helpers/ navbar.haml* ▾ model/ register.haml* mongodb.rb user_dashboard.haml* mongoModule.rb user_profile.haml* user.rb venue.haml* ▾ public/ venues.haml* ▸ bootstrap/ app.rb* ▾ css/ config.ru* styles.css* Gemfile* ▸ images/ Gemfile.lock* ▾ views/ Rakefile* footer.haml* README* index.haml*
  • 91. Download & Install deps mkdir milieu cd milieu wget http://c.spf13.com/OSCON/gettingStarted.tgz tar zxvf gettingStarted.tgz cd app bundle install Using bson (1.6.4) Using bson_ext (1.6.4) Using googlestaticmap (1.1.3) Using haml (3.1.4) Using mongo (1.6.4) Using rack (1.4.1) Using rack-protection (1.2.0) Using shotgun (0.9) Using tilt (1.3.3) Using sinatra (1.3.2) Using bundler (1.1.4) Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
  • 92. Run app shotgun == Shotgun/WEBrick on http://127.0.0.1:9393/ [2012-07-14 11:37:34] INFO WEBrick 1.3.1 [2012-07-14 11:37:34] INFO ruby 1.9.3 (2012-04-20) [x86_64- darwin11.4.0] [2012-07-14 11:37:34] INFO WEBrick::HTTPServer#start: pid=42185 port=9393
  • 93. Open Browser to localhost: 9393
  • 94. Connecting to MongoDB model/mongodb.rb require 'mongo' require './model/mongoModule' require './model/user' CONNECTION = Mongo::Connection.new("localhost") DB = CONNECTION.db('milieu') USERS = DB['users'] VENUES = DB['venues'] CHECKINS = DB['checkins']
  • 95. Listing Venues app.rb get '/venues' do @venues = VENUES.find haml :venues end
  • 96. Listing Venues .container .content views/venues.haml %h2 Venues %table.table.table-striped %thead %tr %th Name %th Address %th Longitude %th Latitude %tbody ~@venues.each do |venue| %tr %td %a{:href => '/venue/' << venue['_id'].to_s}= venue['name'] %td= venue['location']['address'] ? venue['location']['address'] : '&nbsp' %td= venue['location']['geo'][0].round(2) %td= venue['location']['geo'][1].round(2)
  • 97. Listing Venues localhost:9393/venues
  • 98. Paginating Venues app.rb get '/venues/?:page?' do @page = params.fetch('page', 1).to_i pp = 10 @venues = VENUES.find.skip( ( @page - 1 ) * pp).limit(pp) @total_pages = (VENUES.count.to_i / pp).ceil haml :venues end
  • 99. Listing Venues localhost:9393/venues
  • 100. Creating Users Users are a bit special in our app Not just data Special considerations for secure password handling Not complicated on MongoDB side, but slightly complicated on Ruby side
  • 101. Creating Users class User model/user.rb attr_accessor :_id, :name, :email, :email_hash, :salt, :hashed_password, :collection, :updated_at def initialize self.collection = 'users' end def password=(pass) self.salt = random_string(10) unless self.salt self.hashed_password = User.encrypt(pass, self.salt) end def save col = DB[self.collection] self.updated_at = Time.now col.save(self.to_hash) end end
  • 102. Creating Users post '/register' do app.rb u = User.new u.email = params[:email] u.password = params[:password] u.name = params[:name] if u.save() flash("User created") session[:user] = User.auth( params["email"], params["password"]) redirect '/user/' << session[:user].email.to_s << "/dashboard" else tmp = [] u.errors.each do |e| tmp << (e.join("<br/>")) end flash(tmp) redirect '/create' end end
  • 103. Logging in configure do app.rb enable :sessions end before do unless session[:user] == nil @suser = session[:user] end end get '/user/:email/dashboard' do haml :user_dashboard end
  • 104. User Dashboard .container views/user_dashboard.haml .content .page-header -unless @suser == nil? %h2="Dashboard" %br %image{src: "http://www.gravatar.com/avatar/" << @suser.email_hash.to_s << '.png'} %h3= @suser.name.to_s -else redirect '/' %small %a{href: "/user/" << @suser.email.to_s << "/profile"} profile .container#main-topic-nav
  • 105. Dashboard localhost:9393/dashboard
  • 106. Showing a Venue app.rb get '/venue/:_id' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one( { :_id => object_id }) haml :venue end
  • 107. Showing a Venue .row-fluid views/venue.haml .span4 %h2= @venue['name'].to_s %p =@venue['location']['address'].to_s %br= @venue['location']['city'].to_s + ' ' + @venue['location']['state'].to_s + ' ' + @venue['location']['postalCode'].to_s .span8 %image{:src => '' << gmap_url(@venue, {:height => 300, :width => 450}) }
  • 108. A Venue localhost:9393/venue/{id}
  • 109. Nearby Venues app.rb get '/venue/:_id' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) @nearby_venues = VENUES.find( { :'location.geo' => { :$near => [ @venue['location']['geo'][0], @venue['location']['geo'][1]] } }).limit(4).skip(1) haml :venue end
  • 110. Listing Nearby Venues ... views/venue.haml .row-fluid - @nearby_venues.each do |nearby| .span3 %h2 %a{:href => '/venue/' + nearby['_id'].to_s}= nearby['name'].to_s %p =nearby['location']['address'].to_s %br= nearby['location']['city'].to_s + ' ' + nearby['location']['state'].to_s + ' ' + nearby['location']['postalCode'].to_s %a{:href => '/venue/' + nearby['_id'].to_s} %image{:src => '' << gmap_url(nearby, {:height => 150, :width => 150, :zoom => 17}) }
  • 111. Nearby Venues localhost:9393/venue/{id}
  • 112. Checking in app.rb get '/venue/:_id/checkin' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) user = USERS.find_and_modify(:query => { :_id => @suser._id}, :update => {:$inc => { "venues." << object_id.to_s => 1 } }, :new => 1) if user['venues'][params[:_id]] == 1 VENUES.update({ :_id => @venue['_id']}, { :$inc => { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}}) else VENUES.update({ _id: @venue['_id']}, { :$inc => { :'stats.checkinsCount' => 1}}) end flash('Thanks for checking in') redirect '/venue/' + params[:_id] end
  • 113. Checking in app.rb get '/venue/:_id/checkin' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) user = USERS.find_and_modify(:query => { :_id => @suser._id}, :update => {:$inc => { "venues." << object_id.to_s => 1 } }, :new => 1) if user['venues'][params[:_id]] == 1 VENUES.update({ :_id => @venue['_id']}, { :$inc => { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}}) else VENUES.update({ _id: @venue['_id']}, { :$inc => { :'stats.checkinsCount' => 1}}) end flash('Thanks for checking in') redirect '/venue/' + params[:_id] end
  • 114. Checking in app.rb get '/venue/:_id/checkin' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) user = USERS.find_and_modify(:query => { :_id => @suser._id}, :update => {:$inc => { "venues." << object_id.to_s => 1 } }, :new => 1) if user['venues'][params[:_id]] == 1 VENUES.update({ :_id => @venue['_id']}, { :$inc => { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}}) else VENUES.update({ _id: @venue['_id']}, { :$inc => { :'stats.checkinsCount' => 1}}) end flash('Thanks for checking in') redirect '/venue/' + params[:_id] end
  • 115. Checking in app.rb get '/venue/:_id/checkin' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) user = USERS.find_and_modify(:query => { :_id => @suser._id}, :update => {:$inc => { "venues." << object_id.to_s => 1 } }, :new => 1) if user['venues'][params[:_id]] == 1 VENUES.update({ :_id => @venue['_id']}, { :$inc => { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}}) else VENUES.update({ _id: @venue['_id']}, { :$inc => { :'stats.checkinsCount' => 1}}) end flash('Thanks for checking in') redirect '/venue/' + params[:_id] end
  • 116. Checking in app.rb get '/venue/:_id/checkin' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) user = USERS.find_and_modify(:query => { :_id => @suser._id}, :update => {:$inc => { "venues." << object_id.to_s => 1 } }, :new => 1) if user['venues'][params[:_id]] == 1 VENUES.update({ :_id => @venue['_id']}, { :$inc => { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}}) else VENUES.update({ _id: @venue['_id']}, { :$inc => { :'stats.checkinsCount' => 1}}) end flash('Thanks for checking in') redirect '/venue/' + params[:_id] end
  • 117. Checking in app.rb get '/venue/:_id/checkin' do object_id = BSON::ObjectId.from_string(params[:_id]) @venue = VENUES.find_one({ :_id => object_id }) user = USERS.find_and_modify(:query => { :_id => @suser._id}, :update => {:$inc => { "venues." << object_id.to_s => 1 } }, :new => 1) if user['venues'][params[:_id]] == 1 VENUES.update({ :_id => @venue['_id']}, { :$inc => { :'stats.usersCount' => 1, :'stats.checkinsCount' => 1}}) else VENUES.update({ _id: @venue['_id']}, { :$inc => { :'stats.checkinsCount' => 1}}) end flash('Thanks for checking in') redirect '/venue/' + params[:_id] end
  • 118. Checkin In views/venue.haml %p %a.btn.btn-primary.btn-large{:href => '/venue/' + @venue['_id'].to_s + '/checkin'} Check In Here %p =@venue['stats']['usersCount'].ceil.to_s + ' users have checked in here ' + @venue['stats']['checkinsCount'].ceil.to_s + ' times' %p=user_times_at
  • 119. You’ve been here def user_times_at helpers/milieu.rb if logged_in? times = 'You have checked in here ' if !@user.venues.nil? && !@user.venues[params[:_id]].nil? times << @user.venues[params[:_id]].to_s else times << '0' end times << ' times' else times = 'Please <a href='/login'>login</a> to join them.' end end
  • 120. A Venue localhost:9393/venue/{id}
  • 122. Installing the Dependencies gem install heroku Fetching: excon-0.14.3.gem (100%) Fetching: heroku-api-0.2.8.gem (100%) Fetching: netrc-0.7.5.gem (100%) Fetching: mime-types-1.19.gem (100%) Fetching: rest-client-1.6.7.gem (100%) Fetching: launchy-2.1.0.gem (100%) Fetching: rubyzip-0.9.9.gem (100%) Fetching: heroku-2.28.12.gem (100%) Successfully installed excon-0.14.3 Successfully installed heroku-api-0.2.8 Successfully installed netrc-0.7.5 Successfully installed mime-types-1.19 Successfully installed rest-client-1.6.7 Successfully installed launchy-2.1.0 Successfully installed rubyzip-0.9.9 Successfully installed heroku-2.28.12 8 gems installed
  • 124. Create app on Heroku heroku create app_name Enter your Heroku credentials. Email: Your_Email@Your_Domain.com Password (typing will be hidden): Found the following SSH public keys: 1) id_rsa.pub Which would you like to use with your Heroku account? 1 Uploading SSH public key /Users/steve/.ssh/id_rsa.pub... done Creating milieu... done, stack is cedar http://milieu.herokuapp.com/ | git@heroku.com:milieu.git Git remote heroku added
  • 125. Pushing to Heroku git push heroku master Warning: Permanently added the RSA host key for IP address '50.19.85.132' to the list of known hosts. Counting objects: 67, done. Delta compression using up to 4 threads. Compressing objects: 100% (65/65), done. Writing objects: 100% (67/67), 206.04 KiB, done. Total 67 (delta 9), reused 0 (delta 0) -----> Heroku receiving push -----> Removing .DS_Store files -----> Ruby/Rack app detected -----> Installing dependencies using Bundler version 1.2.0.pre Running: bundle install --without development:test --path vendor/bundle -- binstubs bin/ --deployment Fetching gem metadata from http://rubygems.org/....... Installing bson (1.6.4) Installing bson_ext (1.6.4) with native extensions Installing googlestaticmap (1.1.3) Installing haml (3.1.4)
  • 126. Fetching gem metadata from http://rubygems.org/....... Pushing to Heroku Installing bson (1.6.4) Installing bson_ext (1.6.4) with native extensions Installing googlestaticmap (1.1.3) Installing haml (3.1.4) Installing mongo (1.6.4) Installing rack (1.4.1) Installing rack-protection (1.2.0) Installing shotgun (0.9) Installing tilt (1.3.3) Installing sinatra (1.3.2) Using bundler (1.2.0.pre) Your bundle is complete! It was installed into ./vendor/bundle Cleaning up the bundler cache. -----> Writing config/database.yml to read from DATABASE_URL -----> Discovering process types Procfile declares types -> (none) Default types for Ruby/Rack -> console, rake, web -----> Compiled slug size is 1.4MB -----> Launching... done, v3 http://milieu.herokuapp.com deployed to Heroku To git@heroku.com:milieu.git * [new branch] master -> master
  • 127. Adding MongoHQ/Lab heroku addons:add mongohq Adding mongohq to milieu... done, v4 (free) Use `heroku addons:docs mongohq` to view documentation
  • 128. Adjusting Connection model/mongodb.rb if ENV['RACK_ENV'] == 'production' db = URI.parse(ENV['MONGOHQ_URL']) db_name = db.path.gsub(/^//, '') DB = Mongo::Connection.new( db.host, db.port).db(db_name) DB.authenticate(db.user, db.password) unless (db.user.nil? || db.user.nil?) else DB = Mongo::Connection.new( "localhost", 27017).db('milieu') end
  • 129. Config MongoHQ/Lab heroku config === Config Vars for milieu GEM_PATH: vendor/bundle/ruby/1.9.1 LANG: en_US.UTF-8 MONGOHQ_URL: mongodb://heroku:3vw...xv12@staff.mongohq.com:100XX/ appXX PATH: bin:vendor/bundle/ruby/1.9.1/bin:/usr/local/bin:/usr/bin:/bin RACK_ENV: production Password Port Username Server DB
  • 130. Connecting to the shell mongo -u USER -p PASSWORD SERVER:PORT/DB_NAME
  • 131. Importing the Venues mongoimport -u heroku -p PASSWORD -h staff.mongohq.com --port PORT -d DB_NAME -c venues venuesImport.json
  • 132. Debugging heroku logs 2012-07-14T03:24:31+00:00 app[web.1]: /app/vendor/bundle/ruby/1.9.1/gems/mongo-1.6.4/lib/mongo/ connection.rb:420:in `connect': Failed to connect to a master node at localhost:27017 (Mongo::ConnectionFailure) 2012-07-14T03:24:31+00:00 app[web.1]: from /app/vendor/bundle/ruby/1.9.1/gems/mongo-1.6.4/lib/ mongo/connection.rb:594:in `setup' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/vendor/bundle/ruby/1.9.1/gems/mongo-1.6.4/lib/ mongo/connection.rb:130:in `initialize' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/model/mongodb.rb:5:in `new' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/model/mongodb.rb:5:in `<top (required)>' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/app.rb:4:in `<top (required)>' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/config.ru:6:in `require' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/app.rb:4:in `require' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/config.ru:6:in `block in <main>' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/ builder.rb:51:in `instance_eval' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/ builder.rb:51:in `initialize' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/config.ru:1:in `new' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/ builder.rb:40:in `eval' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/config.ru:1:in `<main>' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/ builder.rb:40:in `parse_file' 2012-07-14T03:24:31+00:00 app[web.1]: from /app/vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/ server.rb:200:in `app'
  • 133. Deploying new versions git push heroku Counting objects: 7, done. Delta compression using up to 4 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 424 bytes, done. Total 4 (delta 2), reused 0 (delta 0) -----> Heroku receiving push -----> Removing .DS_Store files -----> Ruby/Rack app detected -----> Installing dependencies using Bundler version 1.2.0.pre Running: bundle install --without development:test --path vendor/bundle -- binstubs bin/ --deployment Using bson (1.6.4) Using bson_ext (1.6.4) Using googlestaticmap (1.1.3) Using haml (3.1.4) Using mongo (1.6.4) Using rack (1.4.1) Using rack-protection (1.2.0)
  • 134. Using googlestaticmap (1.1.3) Deploying new versions Using haml (3.1.4) Using mongo (1.6.4) Using rack (1.4.1) Using rack-protection (1.2.0) Using shotgun (0.9) Using tilt (1.3.3) Using sinatra (1.3.2) Using bundler (1.2.0.pre) Your bundle is complete! It was installed into ./vendor/bundle Cleaning up the bundler cache. -----> Writing config/database.yml to read from DATABASE_URL -----> Discovering process types Procfile declares types -> (none) Default types for Ruby/Rack -> console, rake, web -----> Compiled slug size is 1.4MB -----> Launching... done, v6 http://milieu.herokuapp.com deployed to Heroku To git@heroku.com:milieu.git 9d5d688..ad894be master -> master
  • 136. Next ?
  • 138. Programmin g Challenge
  • 139. Some Ideas ‣Createdifferent user levels ‣Timestamped (admin) Checkins ‣Createinterface ‣Amore complete to add venues dashboard with stats ‣Connectto foursquare ‣Badgesor Categories ‣Login w/twitter
  • 142. http://spf13.com http://github.com/s @spf13 Question download at mongodb.org We’re hiring!! Contact us at jobs@10gen.com

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. Intel&apos;s improved microprocessor chip is introduced April 1, 1974, the 8080 becomes a standard in the computer industry.\n\nThis predates Microsoft, Apple \n
  9. Remember in 1995 there were around 10,000 websites. Mosiac, Lynx, Mozilla (pre netscape) and IE 2.0 were the only web browsers. \nApache (Dec &amp;#x2019;95), Java (&amp;#x2019;96), PHP (June &amp;#x2019;95), and .net didn&amp;#x2019;t exist yet. Linux just barely (1.0 in &amp;#x2019;94)\n
  10. Remember in 1995 there were around 10,000 websites. Mosiac, Lynx, Mozilla (pre netscape) and IE 2.0 were the only web browsers. \nApache (Dec &amp;#x2019;95), Java (&amp;#x2019;96), PHP (June &amp;#x2019;95), and .net didn&amp;#x2019;t exist yet. Linux just barely (1.0 in &amp;#x2019;94)\n
  11. Remember in 1995 there were around 10,000 websites. Mosiac, Lynx, Mozilla (pre netscape) and IE 2.0 were the only web browsers. \nApache (Dec &amp;#x2019;95), Java (&amp;#x2019;96), PHP (June &amp;#x2019;95), and .net didn&amp;#x2019;t exist yet. Linux just barely (1.0 in &amp;#x2019;94)\n
  12. \n
  13. \n
  14. Galaxy III released in May\n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. By reducing transactional semantics the db provides, one can still solve an interesting set of problems where performance is very important, and horizontal scaling then becomes easier.\n\n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. After this I&amp;#x2019;ll jump to my terminal and demo a few things.\n
  68. wget http://c.spf13.com/OSCON/venuesImport.json\nmongoimport -d milieu -c venues venuesImport.json\n\n
  69. After this I&amp;#x2019;ll jump to my terminal and demo a few things.\n
  70. After this I&amp;#x2019;ll jump to my terminal and demo a few things.\n
  71. After this I&amp;#x2019;ll jump to my terminal and demo a few things.\n
  72. After this I&amp;#x2019;ll jump to my terminal and demo a few things.\n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n