18. Entries (populate in
background)
{ _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)
}
19. What we need now
Populate personal feeds (buckets)
Avoid lots of expensive queries
Record what's been read
20. Without bucketing
// Naive query runs every time
db.entries.find(
feed_id: {$in: user_feed_ids}
).sort({date: 1}).limit(25)
21. With bucketing
// A bit smarter: only runs once
entries = db.entries.find(
{ date: {$gt: user_latest },
feed_id: { $in: user_feed_ids }
).sort({date: 1})
25. Viewing a personal feed
// Newest
db.buckets.find(
{ user_id: ObjectId("4e316f236ce9cca7ef17d59d") }
).sort({date: -1}).limit(1)
26. 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)
35. // Collections holding totals for each day, stored
// in a database per month
days_2011_5
days_2011_6
days_2011_7
...
// Totals for each month...
months_2011_1_4
months_2011_5_8
months_2011_9_12
...
36. 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
}
}
42. Reporting
Must provide data at multiple resolutions
(second, minute, etc.).
We have the raw materials for that.
Application assembles the data
intelligently.