Top Banner
2 App Designs Using MongoDB
48
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Getting Started with MongoDB: 4 Application Designs

2 App DesignsUsing MongoDB

Page 2: Getting Started with MongoDB: 4 Application Designs

Kyle [email protected]

Page 3: Getting Started with MongoDB: 4 Application Designs

@hwaet

Page 4: Getting Started with MongoDB: 4 Application Designs

What we'll cover:Brief intro

Feed reader

Website analyitcs

Questions

Page 5: Getting Started with MongoDB: 4 Application Designs

Intro

Page 6: Getting Started with MongoDB: 4 Application Designs

MongoDBRich data model

Replication and automatic failover

Sharding

Page 7: Getting Started with MongoDB: 4 Application Designs

Use casesSocial networking and geolocation

E-commerce

CMS

Analytics

Production deployments: http://is.gd/U0VkG6

Page 8: Getting Started with MongoDB: 4 Application Designs

Demo

Page 9: Getting Started with MongoDB: 4 Application Designs

Feed reader

Page 10: Getting Started with MongoDB: 4 Application Designs

Four collectionsUsers

Feeds

Entries

Buckets

Page 11: Getting Started with MongoDB: 4 Application Designs

Users{ _id: ObjectId("4e316f236ce9cca7ef17d59d"), username: 'kbanker', feeds: [ { _id: ObjectId("4e316f236ce9cca7ef17d54c"), name: "GigaOM" }, { _id: ObjectId("4e316f236ce9cca7ef17d54d"), name: "Salon.com" } { _id: ObjectId("4e316f236ce9cca7ef17d54e"), name: "Foo News" } ], latest: Date(2011, 7, 25)}

Page 12: Getting Started with MongoDB: 4 Application Designs

Indexdb.users.ensureIndex( { username: 1 }, { unique: true } )

Page 13: Getting Started with MongoDB: 4 Application Designs

Feeds{ _id: ObjectId("4e316b8a6ce9cca7ef17d54b"), url: 'http://news.foo.com/feed.xml/', name: 'Foo News', subscriber_count: 2, latest: Date(2011, 7, 25)}

Indexdb.feeds.ensureIndex( { url: 1 }, { unique: true

Page 14: Getting Started with MongoDB: 4 Application Designs

Adding a feed subscription// Upsertdb.feeds.update( { url: 'http://news.foo.com/feed.xml/', name: 'Foo News'}, { $inc: {subscriber_count: 1} }, true )

Page 15: Getting Started with MongoDB: 4 Application Designs

Adding a feed subscription// Add this feed to user feed listdb.users.update( {_id: ObjectId("4e316f236ce9cca7ef17d59d") }, { $addToSet: { feeds: { _id: ObjectId("4e316b8a6ce9cca7ef17d54b"), name: 'Foo News' } })

Page 16: Getting Started with MongoDB: 4 Application Designs

Removing a feedsubscription

db.users.update( { _id: ObjectId("4e316f236ce9cca7ef17d59d") }, { $pull: { feeds: { _id: ObjectId("4e316b8a6ce9cca7ef17d54b"), name: 'Foo News' } } )

Page 17: Getting Started with MongoDB: 4 Application Designs

Removing a feedsubscription

db.feeds.update( {url: 'http://news.foo.com/feed.xml/'}, { $inc: {subscriber_count: -1} } )

Page 18: Getting Started with MongoDB: 4 Application Designs

Entries (populate inbackground)

{ _id: ObjectId("4e316b8a6ce9cca7ef17d54b"), feed_id: ObjectId("4e316b8a6ce9cca7ef17d54b"), title: 'Important person to resign', body: 'A person deemed very important has decided...', reads: 5, date: Date(2011, 7, 27)}

Page 19: Getting Started with MongoDB: 4 Application Designs

What we need nowPopulate personal feeds (buckets)

Avoid lots of expensive queries

Record what's been read

Page 20: Getting Started with MongoDB: 4 Application Designs

Without bucketing// Naive query runs every timedb.entries.find( feed_id: {$in: user_feed_ids}).sort({date: 1}).limit(25)

Page 21: Getting Started with MongoDB: 4 Application Designs

With bucketing// A bit smarter: only runs onceentries = db.entries.find( { date: {$gt: user_latest }, feed_id: { $in: user_feed_ids } ).sort({date: 1})

Page 22: Getting Started with MongoDB: 4 Application Designs

Indexdb.entries.ensureIndex( { date: 1, feed_id: 1} )

Page 23: Getting Started with MongoDB: 4 Application Designs

bucket = { _id: ObjectId("4e3185c26ce9cca7ef17d552"), user_id: ObjectId("4e316f236ce9cca7ef17d59d"), date: Date( 2011, 7, 27 ) n: 100, entries: [ { _id: ObjectId("4e316b8a6ce9cca7ef17d5ac"), feed_id: ObjectId("4e316b8a6ce9cca7ef17d54b"), title: 'Important person to resign', body: 'A person deemed very important has decided...', date: Date(2011, 7, 27), read: false }, { _id: ObjectId("4e316b8a6ce9cca7ef17d5c8"), feed_id: ObjectId("4e316b8a6ce9cca7ef17d54b"), title: 'Panda bear waves hello', body: 'A panda bear at the local zoo...', date: Date(2011, 7, 27), read: false } ]}

Page 24: Getting Started with MongoDB: 4 Application Designs

db.buckets.insert( buckets )db.users.update( { _id: ObjectId("4e316f236ce9cca7ef17d59d") } { $set: { latest: latest_entry_date } })

Page 25: Getting Started with MongoDB: 4 Application Designs

Viewing a personal feed// Newestdb.buckets.find( { user_id: ObjectId("4e316f236ce9cca7ef17d59d") }).sort({date: -1}).limit(1)

Page 26: Getting Started with MongoDB: 4 Application Designs

Viewing a personal feed// Next newest (that's how we paginate)db.buckets.find( { user_id: ObjectId("4e316f236ce9cca7ef17d59d"), date: { $lt: previous_reader_date } }).sort({date: -1}).limit(1)

Page 27: Getting Started with MongoDB: 4 Application Designs

Indexdb.buckets.ensureIndex( { user_id: 1, date: -1 } )

Page 28: Getting Started with MongoDB: 4 Application Designs

Marking a feed itemdb.buckets.update( { user_id: ObjectId("4e316f236ce9cca7ef17d59d"), 'entries.id': ObjectId("4e316b8a6ce9cca7ef17d5c8")}, { $set: { 'entries.$.read' : true })

Page 29: Getting Started with MongoDB: 4 Application Designs

Marking a feed itemdb.entries.update( { _id: ObjectId("4e316b8a6ce9cca7ef17d5c8") }, { $inc: { read: 1 } })

Page 30: Getting Started with MongoDB: 4 Application Designs

Sharding note:Buckets collection is eminently shardable

Shard key: { user_id: 1, date: 1 }

Page 31: Getting Started with MongoDB: 4 Application Designs

Websiteanalyitcs

Page 32: Getting Started with MongoDB: 4 Application Designs

Challenges:Real-time reporting.

Efficient use of space.�

Easily wipe unneeded data.

Page 33: Getting Started with MongoDB: 4 Application Designs

TechniquesPre-aggregate the data.

Pre-construct document structure.

Store emphemeral data in a separatedatabase.

Page 34: Getting Started with MongoDB: 4 Application Designs

Two collections:Each collection gets its own database.

Collections names are time-scoped.

Clean, fast removal of old data.

Page 35: Getting Started with MongoDB: 4 Application Designs

// Collections holding totals for each day, stored// in a database per monthdays_2011_5days_2011_6days_2011_7...// Totals for each month...months_2011_1_4months_2011_5_8months_2011_9_12...

Page 36: Getting Started with MongoDB: 4 Application Designs

Hours and minutes{ _id: { uri: BinData("0beec7b5ea3f0fdbc95d0dd47f35"), day: '2011-5-1' }, total: 2820, hrs: { 0: 500, 1: 700, 2: 450, 3: 343, // ... 4-23 go here } // Minutes are rolling. This gives real-time // numbers for the last hour. So when you increment // minute n, you need to $set minute n-1 to 0. mins: { 1: 12, 2: 10, 3: 5, 4: 34 // ... 5-60 go here }}

Page 37: Getting Started with MongoDB: 4 Application Designs

Updating daydocument...

Page 38: Getting Started with MongoDB: 4 Application Designs

// Update 'days' collection at 5:37 p.m. on 2011-5-1// Might want to queue increments so that $inc is greater// than 1 for each write...id = { uri: BinData("0beec7b5ea3f0fdbc95d0dd47f35"), day: '2011-5-1' };update = { $inc: { total: 1, 'hrs.17': 1, 'mins.37': 1 }, $set: { 'mins.36': 0} };// Update collection containing days 1-5db.days_2011_5.update( id, update );

Page 39: Getting Started with MongoDB: 4 Application Designs

Months and days{ _id: { uri: BinData("0beec7b5ea3f0fdbc95d0dd47f35"), month: '2011-5' }, total: 34173, months: { 1: 4000, 2: 4300, 3: 4200, 4: 5000, 5: 5100, 6: 5700, 7: 5873 // ... 8-12 go here }}

Page 40: Getting Started with MongoDB: 4 Application Designs

Updating monthdocument...

Page 41: Getting Started with MongoDB: 4 Application Designs

// Update 'months' collection at 5:37 p.m. on 2011-5-1query = { uri: BinData("0beec7b5ea3f0fdbc95d0dd47f35"), month: '2011-5' };update = { $inc: { total: 1, 'months.5': 1 } };// Update collection containing days 1-5db.month_2011_1_4.update( query, update );

Page 42: Getting Started with MongoDB: 4 Application Designs

ReportingMust provide data at multiple resolutions(second, minute, etc.).

We have the raw materials for that.

Application assembles the dataintelligently.

Page 43: Getting Started with MongoDB: 4 Application Designs

Summary

Page 44: Getting Started with MongoDB: 4 Application Designs

Feed ReaderRich documents

Incremental modifiers�

Bucketing strategy

Page 45: Getting Started with MongoDB: 4 Application Designs

Website AnalyticsPre-aggregate data

Time-scoped databases and collections

Page 46: Getting Started with MongoDB: 4 Application Designs

http://www.10gen.com/presentations

Page 47: Getting Started with MongoDB: 4 Application Designs

http://manning.com/banker

Page 48: Getting Started with MongoDB: 4 Application Designs

Thank you