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
180
AI: The stuff that nobody shows you
jnunemaker
PRO
9
840
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
9.9k
Why NoSQL?
jnunemaker
PRO
10
1k
Other Decks in Programming
See All in Programming
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
1
280
PostgreSQL 18で考えるUUID主キー
kazuhiro1982
0
400
PHPだって関数型したい 〜できること、できないこと〜 / fp-in-php
jsoizo
1
250
人間の目はかわらない、だからJPEGは30年もつ
yuzneri
9
15k
エンジニアにデザインハーネスを 〜デザインプロセスを規定するためのハーネス〜 / Design harness from an engineer's perspective
rkaga
2
1.7k
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
1
220
Welcome to the "Parametricity" 🏙️ − Generic だけど Specific な世界 −
guvalif
PRO
1
180
SLOをサービス品質の共通言語にするために 取り組んできたこと
wakana0222
0
550
継続モナドとリアクティブプログラミング
yukikurage
3
650
『コードを書く以外の』エンジニアリング〜課金基盤移行プロジェクト推進のためのTips4選
yuriko1211
0
540
なぜ関数型プログラミングで「型」と「証明」が語られるのか #fp_matsuri
kajitack
3
1k
才能?センス?知らん、 続けたもん勝ちだ。-- 結婚・出産・癌を越えてなお、私がプロダクトを創り続ける理由
16bitidol
2
910
Featured
See All Featured
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
200
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
390
Design in an AI World
tapps
1
270
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
400
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
Documentation Writing (for coders)
carmenintech
77
5.4k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
450
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.6k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
340
Code Reviewing Like a Champion
maltzj
528
40k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
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