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
MongoDB for Analytics
Search
John Nunemaker
PRO
October 18, 2011
Programming
16
30k
MongoDB for Analytics
Presented at Mongo Chicago 2011.
John Nunemaker
PRO
October 18, 2011
Tweet
Share
More Decks by John Nunemaker
See All by John Nunemaker
Atom
jnunemaker
PRO
10
4.3k
MongoDB for Analytics
jnunemaker
PRO
11
950
Addicted to Stable
jnunemaker
PRO
32
2.6k
MongoDB for Analytics
jnunemaker
PRO
21
2.3k
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.6k
Why NoSQL?
jnunemaker
PRO
10
960
Don't Repeat Yourself, Repeat Others
jnunemaker
PRO
7
3.5k
I Have No Talent
jnunemaker
PRO
14
980
Why MongoDB Is Awesome
jnunemaker
PRO
18
4.5k
Other Decks in Programming
See All in Programming
XP, Testing and ninja testing ZOZ5
m_seki
2
280
ABEMAモバイルアプリが Kotlin Multiplatformと歩んだ5年 ─ 導入と運用、成功と課題 / iOSDC 2025
akkyie
0
320
Le côté obscur des IA génératives
pascallemerrer
0
120
Introducing ReActionView: A new ActionView-Compatible ERB Engine @ Kaigi on Rails 2025, Tokyo, Japan
marcoroth
3
920
エンジニアとして高みを目指す、 利益を生み出す設計の考え方 / design-for-profit
minodriven
23
12k
monorepo の Go テストをはやくした〜い!~最小の依存解決への道のり~ / faster-testing-of-monorepos
convto
2
380
CSC509 Lecture 03
javiergs
PRO
0
330
WebエンジニアがSwiftをブラウザで動かすプレイグラウンドを作ってみた
ohmori_yusuke
0
170
iOSアプリの信頼性を向上させる取り組み/ios-app-improve-reliability
shino8rayu9
0
150
Pull-Requestの内容を1クリックで動作確認可能にするワークフロー
natmark
2
450
iOSエンジニア向けの英語学習アプリを作る!
yukawashouhei
0
170
iOS 17で追加されたSubscriptionStoreView を利用して5分でサブスク実装チャレンジ
natmark
0
580
Featured
See All Featured
Rails Girls Zürich Keynote
gr2m
95
14k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
2.6k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Agile that works and the tools we love
rasmusluckow
331
21k
How GitHub (no longer) Works
holman
315
140k
Build your cross-platform service in a week with App Engine
jlugia
232
18k
Gamification - CAS2011
davidbonilla
81
5.5k
The Power of CSS Pseudo Elements
geoffreycrofte
79
6k
BBQ
matthewcrist
89
9.8k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.1k
Transcript
Ordered List John Nunemaker MongoChi 2011 October 18, 2011 MongoDB
for Analytics A loving conversation with @jnunemaker
Background As presented through interpretive dance
None
None
None
~1 month Of evenings and weekends
~4 dog years Since public launch
~6 tiny servers 2 web, 2 app, 2 db
~1-2 Million Page views per day
None
None
Implementation Imma show you how we do what we do
baby
Doing It Live No aggregate querying
get('/track.gif') do Hit.record(...) TrackGif end
class Hit def record site.atomic_update(site_updates) Resolution.record(self) Technology.record(self) Location.record(self) Referrer.record(self) Content.record(self)
Search.record(self) Notification.record(self) View.record(self) end end
class Resolution def record(hit) query = {'_id' => "..."} update
= {'$inc' => {}} update['$inc']["sx.#{hit.screenx}"] = 1 update['$inc']["bx.#{hit.browserx}"] = 1 update['$inc']["by.#{hit.browsery}"] = 1 collection(hit.created_on) .update(query, update, :upsert => true) end end end
Pros
Pros Space
Pros Space RAM
Pros Space RAM Reads
Pros Space RAM Reads Live
Cons
Cons Writes
Cons Writes Constraints
Cons Writes Constraints More Forethought
Cons Writes Constraints More Forethought No raw data
Time Frame Minute, hour, month, day, year, forever?
# of Variations One document vs many
Single Document Per Time Frame
None
{ "t" => 336381, "u" => 158951, "2011" => {
"02" => { "18" => { "t" => 9, "u" => 6 } } } }
{ '$inc' => { 't' => 1, 'u' => 1,
'2011.02.18.t' => 1, '2011.02.18.u' => 1, } }
Single Document For all ranges in time frame
None
{ "_id" =>"...:10", "bx" => { "320" => 85, "480"
=> 318, "800" => 1938, "1024" => 5033, "1280" => 6288, "1440" => 2323, "1600" => 3817, "2000" => 137 }, "by" => { "480" => 2205, "600" => 7359,
"600" => 7359, "768" => 4515, "900" => 3833, "1024"
=> 2026 }, "sx" => { "320" => 191, "480" => 179, "800" => 195, "1024" => 1059, "1280" => 5861, "1440" => 3533, "1600" => 7675, "2000" => 1279 } }
{ '$inc' => { 'sx.1440' => 1, 'bx.1280' => 1,
'by.768' => 1, } }
Many Documents Search terms, content, referrers...
None
[ { "_id" => "<oid>:<hash>", "t" => "ruby class variables",
"sid" => BSON::ObjectId('<oid>'), "v" => 352 }, { "_id" => "<oid>:<hash>", "t" => "ruby unless", "sid" => BSON::ObjectId('<oid>'), "v" => 347 }, ]
Writes {'_id' => "#{site_id}:#{hash}"}
Reads [['sid', 1], ['v', -1]]
Growth The best laid plans of mice and men
Partition Hot Data Currently using collections for time frames
Bigger, Faster Server More CPU, RAM, Disk Space
Users Sites Content Referrers Terms Engines Resolutions Locations Users Sites
Content Referrers Terms Engines Resolutions Locations
Partition by Function Spread writes across a few servers
Users Sites Content Referrers Terms Engines Resolutions Locations
Partition by Server Spread writes across a ton of servers,
way down the road, not worried yet
Ordered List Thank you!
[email protected]
John Nunemaker MongoChi 2011 October
18, 2011 @jnunemaker