Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
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
190
AI: The stuff that nobody shows you
jnunemaker
PRO
9
960
Atom
jnunemaker
PRO
10
5.2k
MongoDB for Analytics
jnunemaker
PRO
11
1.1k
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
1k
Other Decks in Programming
See All in Programming
PyConJP2026_wat_Python × Signal Processing: How to Draw Pictures with Sound Using Spectrogram Art
wat
0
650
Kiroで創り、AgentCoreで繋ぐ!AWSで実践する「AI-DLC」から「AIエージェント統合」までの最新地図
licux
1
180
高専、大学編入、そして未踏へ〜プロダクト開発とキャリアの歩み - Technical College, University Transfer, and On to “Mitou” / My Journey in Product Development and Career
pkmiya
0
130
自分的「カンファレンスの楽しみ方」
syumai
0
180
高専キャリア LT 発表内容
crysta1221
6
5.4k
Hello, Hiroshima Geospatial Data! — Exploring DoboX with Python
ra0kley
0
150
iOS開発×AI駆動開発 〜最近使って便利だったスキルの話〜
nogu66
0
140
「つくるAI」だけではバグは見つからない ~テストに必要な「見つけるAI」を分離させる戦略~
mfunaki
0
230
[PyCon KR 2026] More Variants, More Diversity for AI Accelerators
achimnol
0
130
承認済みなのに差戻しできてしまうバグ、型で潰せます
shinchit
0
130
私のClaude Code活用法 (個人開発編) - PHPerKaigi mini #4(2026/08/24)
panda_program
1
200
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
340
Featured
See All Featured
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
290
Building the Perfect Custom Keyboard
takai
2
860
Designing for Timeless Needs
cassininazir
1
470
Abbi's Birthday
coloredviolet
3
9.7k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
660
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
410
Everyday Curiosity
cassininazir
0
310
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
370
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
570
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
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