This tutorial will introduce the features of MongoDB by building a simple location-based application using MongoDB. The tutorial will cover the basics of MongoDB’s document model, query language, map-reduce framework and deployment architecture.
The tutorial will be divided into 5 sections:
Data modeling with MongoDB: documents, collections and databases
Querying your data: simple queries, geospatial queries, and text-searching
Writes and updates: using MongoDB’s atomic update modifiers
Trending and analytics: Using mapreduce and MongoDB’s aggregation framework
Deploying the sample application
Besides the knowledge to start building their own applications with MongoDB, attendees will finish the session with a working application they use to check into locations around Portland from any HTML5 enabled phone!
TUTORIAL PREREQUISITES
Each attendee should have a running version of MongoDB. Preferably the latest unstable release 2.1.x, but any install after 2.0 should be fine. You can dowload MongoDB at http://www.mongodb.org/downloads.
Instructions for installing MongoDB are at http://docs.mongodb.org/manual/installation/.
Additionally we will be building an app in Ruby. Ruby 1.9.3+ is required for this. The current latest version of ruby is 1.9.3-p194.
For windows download the http://rubyinstaller.org/
For OSX download http://unfiniti.com/software/mac/jewelrybox/
For linux most users should know how to for their own distributions.
We will be using the following GEMs and they MUST BE installed ahead of time so you can be ahead of the game and safe in the event that the Internet isn’t accommodating.
bson (1.6.4)
bson_ext (1.6.4)
haml (3.1.4)
mongo (1.6.4)
rack (1.4.1)
rack-protection (1.2.0)
rack shotgun (0.9)
sinatra (1.3.2)
tilt (1.3.3)
Prior ruby experience isn’t required for this. We will NOT be using rails for this app.
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
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.
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!
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
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
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
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
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
82. Control Structures
if condition
# ...
elsif other_condition
# ...
end
unless condition
# ...
end
while
# ...
end
83.
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
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
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
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
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
142. http://spf13.com
http://github.com/s
@spf13
Question
download at mongodb.org
We’re hiring!! Contact us at jobs@10gen.com
Notas do Editor
\n
\n
\n
\n
\n
\n
\n
Intel's improved microprocessor chip is introduced April 1, 1974, the 8080 becomes a standard in the computer industry.\n\nThis predates Microsoft, Apple \n
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 &#x2019;95), Java (&#x2019;96), PHP (June &#x2019;95), and .net didn&#x2019;t exist yet. Linux just barely (1.0 in &#x2019;94)\n
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 &#x2019;95), Java (&#x2019;96), PHP (June &#x2019;95), and .net didn&#x2019;t exist yet. Linux just barely (1.0 in &#x2019;94)\n
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 &#x2019;95), Java (&#x2019;96), PHP (June &#x2019;95), and .net didn&#x2019;t exist yet. Linux just barely (1.0 in &#x2019;94)\n
\n
\n
Galaxy III released in May\n
\n
\n
\n
\n
\n
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
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
After this I&#x2019;ll jump to my terminal and demo a few things.\n
wget http://c.spf13.com/OSCON/venuesImport.json\nmongoimport -d milieu -c venues venuesImport.json\n\n
After this I&#x2019;ll jump to my terminal and demo a few things.\n
After this I&#x2019;ll jump to my terminal and demo a few things.\n
After this I&#x2019;ll jump to my terminal and demo a few things.\n
After this I&#x2019;ll jump to my terminal and demo a few things.\n