Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Why MongoDB Is Awesome
Search
John Nunemaker
PRO
December 30, 2010
Programming
4.6k
18
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Why MongoDB Is Awesome
John Nunemaker
PRO
December 30, 2010
More Decks by John Nunemaker
See All by John Nunemaker
Remote First: Building Distributed Teams that Win
jnunemaker
PRO
1
210
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.1k
Atom
jnunemaker
PRO
10
5.2k
MongoDB for Analytics
jnunemaker
PRO
11
1.2k
Addicted to Stable
jnunemaker
PRO
32
2.9k
MongoDB for Analytics
jnunemaker
PRO
21
2.3k
MongoDB for Analytics
jnunemaker
PRO
16
30k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Why NoSQL?
jnunemaker
PRO
10
1.1k
Other Decks in Programming
See All in Programming
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
340
Ghostty + Neovimで作る 透明でカッコ良い開発環境
j341nono
0
150
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
1
680
SREの越境 / SRE Collaboration
y0hgi
2
290
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
330
手動確認はもう限界 〜XCUITestでCustom URL Schemeの遷移を起動種別ごとに自動テストする〜 / Testing Custom URL Schemes with XCUITest
otouto
0
360
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
280
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
610
AI Agent時代のリアーキテクチャ戦略と実践
hokaccha
9
5.2k
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
5
4.4k
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
280
App Intentsのビルドプロセスを支える技術
kntkymt
0
480
Featured
See All Featured
sira's awesome portfolio website redesign presentation
elsirapls
0
430
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
450
What does AI have to do with Human Rights?
axbom
PRO
1
2.4k
GraphQLとの向き合い方2022年版
quramy
50
15k
Designing for humans not robots
tammielis
254
26k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
520
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
530
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
250
How to Think Like a Performance Engineer
csswizardry
28
2.8k
Transcript
Ordered List John Nunemaker DevNation Chicago, IL May 15, 2010
Why MongoDB Is Awesome
@jnunemaker I am user #4,243 on Twitter
“ John Nunemaker ...the best features of key/ values stores,
document databases and relational databases in one. RailsTips.org June '09
Created by
I
I A LOT
that I am on the payroll. Which has led some
people to believe
...but I am not.
Satisfied User I am merely a
Try Easy To
In Your Browser Easy to Try
http://try.mongodb.org/
On Your Computer Easy to Try
$ wget http://downloads.mongodb.org/osx/mongodb-osx-x86_64-1.4.2.tgz
$ wget http://downloads.mongodb.org/osx/mongodb-osx-x86_64-1.4.2.tgz $ tar -xf mongodb-osx-x86_64-1.4.2.tgz
$ mkdir -p /data/db $ wget http://downloads.mongodb.org/osx/mongodb-osx-x86_64-1.4.2.tgz $ tar -xf
mongodb-osx-x86_64-1.4.2.tgz
$ mkdir -p /data/db $ wget http://downloads.mongodb.org/osx/mongodb-osx-x86_64-1.4.2.tgz $ tar -xf
mongodb-osx-x86_64-1.4.2.tgz $ mongodb-osx-x86_64-1.4.2/bin/mongod
http://www.mongodb.org/display/DOCS/Downloads
From Your Language Easy to Try
http://www.mongodb.org/display/DOCS/Drivers
Understand Easy To
Similar Terms Easy to Understand
Database == Database
> show dbs admin harmony-development harmony-test local ... > use
harmony-development switched to db harmony-development > show collections accounts activities assets items ...
Collection == Table
> db.accounts harmony-development.accounts > db.accounts.count() 1 > db.accounts.find().forEach(function(doc) { print(tojson(doc));
});
Document == Row
{ "_id" : ObjectId("4be97eaebcd1b30e86000003"), "title" : "Ordered List", "creator_id" :
ObjectId("4be97eadbcd1b30e86000001"), "memberships" : [ ObjectId("4be97eadbcd1b30e86000001"), ObjectId("4be97eaebcd1b30e86000002") ] }
Similar Functionality Easy to Understand
Dynamic Queries http://www.mongodb.org/display/DOCS/Querying http://www.mongodb.org/display/DOCS/Advanced+Queries
> use testing switched to db testing > db.colors.insert({name:'red', primary:true})
> db.colors.insert({name:'green', primary:true}) > db.colors.insert({name:'blue', primary:true}) > db.colors.insert({name:'purple', primary:false}) > db.colors.insert({name:'orange', primary:false}) > db.colors.insert({name:'yellow', primary:false})
> var cursor = db.colors.find() > cursor.next() { "_id" :
ObjectId("4bed7aeb0b4acd070c593ba6"), "name" : "red", "primary" : true }
> cursor { "_id" : ObjectId("4bed7af40b4acd070c593ba7"), "name" : "green", "primary"
: true } { "_id" : ObjectId("4bed7af80b4acd070c593ba8"), "name" : "blue", "primary" : true } { "_id" : ObjectId("4bed7b570b4acd070c593ba9"), "name" : "purple", "primary" : false } { "_id" : ObjectId("4bed7b6a0b4acd070c593baa"), "name" : "orange", "primary" : false } { "_id" : ObjectId("4bed7b7d0b4acd070c593bab"), "name" : "yellow", "primary" : false }
SELECT * from colors WHERE name = 'green'
> db.colors.find({name:'green'}) { "_id" : ObjectId("4bed7af40b4acd070c593ba7"), "name" : "green", "primary"
: true } SELECT * from colors WHERE name = 'green'
SELECT name from colors WHERE primary = 1
SELECT name from colors WHERE primary = 1 > db.colors.find({primary:true},
{name:true}) { "_id" : ObjectId("4bed7aeb0b4acd070c593ba6"), "name" : "red" } { "_id" : ObjectId("4bed7af40b4acd070c593ba7"), "name" : "green" } { "_id" : ObjectId("4bed7af80b4acd070c593ba8"), "name" : "blue" }
> db.colors.find({name:/l/}) { "_id" : ObjectId("4bed7af80b4acd070c593ba8"), "name" : "blue", "primary"
: true } { "_id" : ObjectId("4bed7b570b4acd070c593ba9"), "name" : "purple", "primary" : false } { "_id" : ObjectId("4bed7b7d0b4acd070c593bab"), "name" : "yellow", "primary" : false }
> db.colors.find({primary:true}).sort({name:1}).limit(1) { "_id" : ObjectId("4bed7af80b4acd070c593ba8"), "name" : "blue", "primary"
: true }
> db.colors.find({primary:true}).sort({name:1}).limit(1) { "_id" : ObjectId("4bed7af80b4acd070c593ba8"), "name" : "blue", "primary"
: true } > db.colors.find({primary:true}).sort({name:-1}).limit(1) { "_id" : ObjectId("4bed7aeb0b4acd070c593ba6"), "name" : "red", "primary" : true }
> db.colors.find({primary:true}).sort({name:1}).limit(1) { "_id" : ObjectId("4bed7af80b4acd070c593ba8"), "name" : "blue", "primary"
: true } > db.colors.find({primary:true}).sort({name:-1}).limit(1) { "_id" : ObjectId("4bed7aeb0b4acd070c593ba6"), "name" : "red", "primary" : true } > db.colors.find({primary:true}).sort({name:1}).skip(1).limit(1) { "_id" : ObjectId("4bed7af40b4acd070c593ba7"), "name" : "green", "primary" : true }
> db.people.insert({name:'John', age:28}) > db.people.insert({name:'Steve', age:29}) > db.people.insert({name:'Steph', age:27})
SELECT * from people WHERE age > 27
> db.people.find({age: {$gt: 27}}) { "_id" : ObjectId("4bed80b20b4acd070c593bac"), "name" :
"John", "age" : 28 } { "_id" : ObjectId("4bed80bb0b4acd070c593bad"), "name" : "Steve", "age" : 29 } SELECT * from people WHERE age > 27
SELECT * from people WHERE age <= 27
SELECT * from people WHERE age <= 27 > db.people.find({age:
{$lte: 27}}) { "_id" : ObjectId("4bed80c10b4acd070c593bae"), "name" : "Steph", "age" : 27 }
$gt $gte $lt $lte $ne $in $nin $mod $all $size
$exists $type $elemMatch $not $where
Indexes http://www.mongodb.org/display/DOCS/Indexes
// single ascending > db.colors.ensureIndex({name: 1})
// single ascending > db.colors.ensureIndex({name: 1}) // single descending >
db.colors.ensureIndex({created_at: -1})
// single ascending > db.colors.ensureIndex({name: 1}) // unique > db.colors.ensureIndex({email:
1}, {unique: true}) // single descending > db.colors.ensureIndex({created_at: -1})
// single ascending > db.colors.ensureIndex({name: 1}) // non-blocking in background
> db.colors.ensureIndex({name: 1}, {background: true}) // unique > db.colors.ensureIndex({email: 1}, {unique: true}) // single descending > db.colors.ensureIndex({created_at: -1})
// single ascending > db.colors.ensureIndex({name: 1}) // compound > db.colors.ensureIndex({name:
1, created_at: -1}) // non-blocking in background > db.colors.ensureIndex({name: 1}, {background: true}) // unique > db.colors.ensureIndex({email: 1}, {unique: true}) // single descending > db.colors.ensureIndex({created_at: -1})
Aggregation http://www.mongodb.org/display/DOCS/Aggregation
> db.colors.count() 6 > db.colors.count ({primary:true}) 3
> db.colors.distinct('name') [ "blue", "green", "orange", "purple", "red", "yellow" ]
> db.people.distinct('name', {age:28}) [ "John" ]
> db.items.insert({title:'Home', template:'home'}) > db.items.insert({title:'What We Do', template:'page'}) > db.items.insert({title:'Our
Writing', template:'page'}) > db.items.insert({title:'Who We Are', template:'page'}) > db.items.insert({title:'Hire Us', template:'page'}) > var key = {template: true}; > var initial = {count:0}; > var reduce = function(obj, prev) { prev.count += 1; }; > db.items.group({key:key, initial:initial, reduce:reduce}) [ {"template" : "home", "count" : 1}, {"template" : "page", "count" : 4} ]
> db.items.insert({tags: ['dog', 'cat']}) > db.items.insert({tags: ['dog']}) > db.items.insert({tags: ['dog',
'mouse']}) > db.items.insert({tags: ['dog', 'mouse', 'hippo']}) > db.items.insert({tags: ['dog', 'mouse', 'hippo']}) > db.items.insert({tags: ['dog', 'hippo']})
> var map = function() { this.tags.forEach(function(t) { emit(t, {count:
1}); }); }
> var reduce = function(key, values) { var count =
0; for(var i=0, len=values.length; i<len; i++) { count += values[i].count; } return {count: count}; }
> var result = db.items.mapReduce(map, reduce);
> var result = db.items.mapReduce(map, reduce); > result { "ok"
: 1, "timeMillis" : 86, "result" : "tmp.mr.mapreduce_1273861517_683", "counts" : { "input" : 6, "emit" : 13, "output" : 4 } }
> db[result.result].find() { "_id" : "cat", "value" : { "count"
: 1 } } { "_id" : "dog", "value" : { "count" : 6 } } { "_id" : "hippo", "value" : { "count" : 3 } } { "_id" : "mouse", "value" : { "count" : 3 } }
Similar Data Types Easy to Understand
Array, Binary, Boolean, DateTime, DB Reference, Embedded Object, Integer, Null,
ObjectId, RegExp, String, Symbol, Timestamp
None
> db.people.insert({ name : 'John', awesome : true, shows :
['Dexter', 'LOST', 'How I Met Your Mother'], info : { age : 28, home: 'South Bend, IN', dob : (new Date('November 25, 1981')) } })
> var me = db.people.findOne({name:'John'}) > me.name John > me.awesome
true > me.shows[1] LOST > me.info.age 28 > me.info.dob.getFullYear() 1981
> db.people.find({'info.age': 28}) { "_id" : ObjectId("4bed9cba0b4acd070c593bc5"), "name" : "John"
}
> db.people.find({'info.age': 28}) { "_id" : ObjectId("4bed9cba0b4acd070c593bc5"), "name" : "John"
} > db.people.find({shows:'Dexter'}) { "_id" : ObjectId("4bed9cba0b4acd070c593bc5"), "name" : "John" }
> db.people.find({'info.age': 28}) { "_id" : ObjectId("4bed9cba0b4acd070c593bc5"), "name" : "John"
} > db.people.find({shows:'Dexter'}) { "_id" : ObjectId("4bed9cba0b4acd070c593bc5"), "name" : "John" } > db.people.find({shows:{$in:['Dexter', 'LOST']}}) { "_id" : ObjectId("4bed9cba0b4acd070c593bc5"), "name" : "John" }
Similar Relationships Easy to Understand
One to Many
1. Normalized
// insert post > db.posts.insert({title:'Why Mongo Rocks'}); > var post
= db.posts.findOne({title:'Why Mongo Rocks'});
// insert post > db.posts.insert({title:'Why Mongo Rocks'}); > var post
= db.posts.findOne({title:'Why Mongo Rocks'}); // insert comment > db.comments.insert({ name :'John', body :'Because...', post_id : post._id }); > var comment = db.comments.findOne({name:'John'});
> db.comments.find({post_id: post._id}) { "_id" : ObjectId("4bee1cc79e89db4e12bf78de"), "name" : "John",
"body" : "Because...", "post_id" : ObjectId("4bee1c519e89db4e12bf78dd") } SELECT * FROM comments WHERE post_id = #{post.id}
> db.posts.find({_id: comment.post_id}) { "_id" : ObjectId("4bee1c519e89db4e12bf78dd"), "title" : "Why
Mongo Rocks" } SELECT * FROM posts WHERE id = #{comment.id}
2. Embedded
// insert post AND comments > db.posts.insert({ title:'Why Mongo Rocks',
comments: [ {name:'John', body:'Because...'}, {name:'Steve', body:'Uh huh!'} ] })
> var post = db.posts.find({title:'Why Mongo Rocks'});
> var post = db.posts.find({title:'Why Mongo Rocks'}); > post {
"_id" : ObjectId("4bee21259e89db4e12bf78df"), "title" : "Why Mongo Rocks", "comments" : [ {"name": "John", "body": "Because..."}, {"name": "Steve", "body": "Uh huh!"} ] }
> db.posts.find({'comments.name':'John'})
> db.posts.find({ comments: { $elemMatch: {name:'John'} } }) > db.posts.find({'comments.name':'John'})
// insert post AND comments AND threads! > db.posts.insert({ title:'Why
Mongo Rocks', comments: [ { name:'John', body:'Because...', comments: [ {name:'Frank', body:'You are crazy!'}, {name:'Billy', body:'Frank Furter!'} ] } ] })
> db.posts.insert({ title : 'Why Mongo Rocks', tags : ['mongodb',
'databases'] })
> db.posts.insert({ title : 'Why Mongo Rocks', tags : ['mongodb',
'databases'] }) > db.posts.ensureIndex({tags:1})
Some Notes
Some Notes Embedding is pre-joining
Some Notes Embedding is pre-joining Embed when document always appears
with parent
Some Notes Embedding is pre-joining Embed when document always appears
with parent 4MB document size limit
Many to Many
> db.sites.insert({domain: 'orderedlist.com'}) > db.sites.insert({domain: 'railstips.org'}) > db.sites.find() { "_id"
: ObjectId("4bee280f9e89db4e12bf78e2"), "domain": "orderedlist.com" } { "_id" : ObjectId("4bee283c9e89db4e12bf78e3"), "domain": "railstips.org" }
> db.users.insert({ name: 'John', authorizations: [ ObjectId('4bee280f9e89db4e12bf78e2'), ObjectId('4bee283c9e89db4e12bf78e3') ] })
> db.users.insert({ name: 'Steve', authorizations: [ ObjectId('4bee280f9e89db4e12bf78e2') ] })
> var orderedlist = db.sites.findOne({domain:'orderedlist.com'}) > db.users.find({authorizations:orderedlist._id}) // john and
steve > var railstips = db.sites.findOne({domain:'railstips.org'}) > db.users.find({authorizations:railstips._id}) // john
> var john = db.users.findOne({name:'John'}) > db.sites.find({_id:{$in: john.authorizations}}) // orderedlist.com
and railstips.org
Learn Easy To
By Email http://groups.google.com/group/mongodb-user
By IRC irc://irc.freenode.net/#mongodb
By Web http://mongodb.org/ http://mongotips.com/
By Book http://www.10gen.com/books http://cookbook.mongodb.org/
By Conference http://www.10gen.com/events http://windycitydb.org/
By Training http://ideafoundry.info/mongodb
Ordered List Thank you!
[email protected]
John Nunemaker DevNation Chicago, IL
May 15, 2010 @jnunemaker