Bucket pattern for time-series data in MongoDB - Step-by-Step Execution
db.sensorData.insertOne({
bucketStart: ISODate("2024-06-01T00:00:00Z"),
readings: [
{time: ISODate("2024-06-01T00:01:00Z"), value: 20},
{time: ISODate("2024-06-01T00:02:00Z"), value: 21}
]
})| Step | Action | Data State | Result |
|---|---|---|---|
| 1 | Receive new data point at 00:01 | No buckets yet | Prepare to create bucket for 00:00-01:00 |
| 2 | Check if bucket for 00:00 exists | No bucket found | Create new bucket document with bucketStart 00:00 |
| 3 | Insert data point into readings array | Bucket readings empty | Readings array now has 1 data point |
| 4 | Receive new data point at 00:02 | Bucket for 00:00 exists with 1 reading | Add new data point to readings array |
| 5 | Query data for 00:00-01:00 | One bucket with 2 readings | Return bucket document with both readings |
| 6 | Extract individual readings from bucket | Bucket readings array | Two separate data points available for analysis |
| 7 | Receive data point at 01:05 | Bucket for 00:00 full, no bucket for 01:00 | Create new bucket for 01:00 interval |
| 8 | Insert data point into new bucket | New bucket readings empty | Readings array now has 1 data point |
| 9 | Query data for 01:00-02:00 | One bucket with 1 reading | Return bucket document with that reading |
| 10 | End of demonstration | Buckets created and queried | Efficient storage and retrieval achieved |
| Variable | Start | After Step 3 | After Step 4 | After Step 7 | After Step 8 | Final |
|---|---|---|---|---|---|---|
| buckets | {} | {"00:00": [{time: "00:01", value: 20}]} | {"00:00": [{time: "00:01", value: 20}, {time: "00:02", value: 21}]} | {"00:00": [...], "01:00": []} | {"00:00": [...], "01:00": [{time: "01:05", value: "X"}]} | {"00:00": [...], "01:00": [...] } |
Bucket pattern groups many time-series points into one document per time interval. Each bucket document has a start time and an array of readings. New data points go into the bucket matching their time interval. Queries retrieve buckets for a time range, then extract points. This reduces document count and improves performance.
Practice
What is the main purpose of using the bucket pattern in MongoDB for time-series data?
Solution
Step 1: Understand the bucket pattern concept
The bucket pattern groups multiple time-series records into fewer documents to reduce storage and improve query speed.Step 2: Compare options with the bucket pattern purpose
Only To group many time-series records into fewer documents for efficiency correctly describes grouping records into fewer documents for efficiency.Final Answer:
To group many time-series records into fewer documents for efficiency -> Option AQuick Check:
Bucket pattern groups records = A [OK]
- Thinking bucket pattern deletes data automatically
- Confusing bucket pattern with indexing every record
- Believing bucket pattern changes data format
Which of the following is the correct way to use $bucket to group documents by time ranges in MongoDB?
{ $bucket: { groupBy: "$timestamp", boundaries: [ISODate("2024-01-01"), ISODate("2024-02-01"), ISODate("2024-03-01")], default: "Other" } }Solution
Step 1: Check the required fields for $bucket
The$bucketstage requires agroupByfield and aboundariesarray to define bucket ranges.Step 2: Validate the boundaries and groupBy usage
Using$bucketwithgroupByon timestamp and specifying boundaries as dates correctly usesgroupByon timestamp and boundaries as ISODate objects, which is valid for time-series bucketing.Final Answer:
Using $bucket with groupBy on timestamp and specifying boundaries as dates -> Option DQuick Check:
$bucket needs groupBy and boundaries = A [OK]
- Omitting boundaries array causes error
- Using strings instead of date objects for time boundaries
- Missing groupBy field in $bucket stage
Given the following aggregation pipeline using $bucket on a collection with timestamps:
[{ $bucket: { groupBy: "$timestamp", boundaries: [ISODate("2024-01-01"), ISODate("2024-02-01"), ISODate("2024-03-01")], default: "Other", output: { count: { $sum: 1 } } } }]What will be the output if the collection has 5 documents with timestamps in January 2024 and 3 documents in March 2024?
Solution
Step 1: Understand bucket boundaries and grouping
Documents with timestamps from 2024-01-01 to before 2024-02-01 go to first bucket; 2024-02-01 to before 2024-03-01 to second; others to default "Other".Step 2: Assign documents to buckets based on timestamps
5 docs in January fall in first bucket; 3 docs in March fall outside boundaries, so go to "Other"; second bucket has 0 docs.Final Answer:
[{_id: ISODate("2024-01-01"), count: 5}, {_id: ISODate("2024-02-01"), count: 0}, {_id: "Other", count: 3}] -> Option AQuick Check:
Docs in Jan = 5, in Other = 3, Feb bucket empty = C [OK]
- Ignoring the default bucket for out-of-bound timestamps
- Assuming March docs fall in February bucket
- Summing all docs into one bucket
Consider this aggregation pipeline snippet using $bucket:
{ $bucket: { groupBy: "$time", boundaries: [ISODate("2024-01-01")], output: { count: { $sum: 1 } } } }What is the error in this pipeline?
Solution
Step 1: Check boundaries array requirements
The boundaries array must have at least two elements to define bucket ranges properly, including an upper boundary for the last bucket.Step 2: Identify missing upper boundary
The boundaries array has only one date, so it cannot define any bucket ranges, causing an error.Final Answer:
The boundaries array must have at least two elements defining ranges -> Option CQuick Check:
Boundaries must have at least 2 elements = A [OK]
- Using boundaries array with fewer than two elements
- Assuming groupBy field name must be 'timestamp'
- Thinking output fields are not allowed in $bucket
You want to store sensor readings every minute for a month using the bucket pattern. Each bucket should hold data for one hour. Which boundaries array correctly defines the buckets for January 1, 2024?
Solution
Step 1: Understand bucket boundaries for hourly buckets
Each bucket covers one hour, so boundaries must be every hour mark from midnight to next day midnight.Step 2: Check options for correct hourly boundaries
[ISODate("2024-01-01T00:00:00Z"), ISODate("2024-01-01T01:00:00Z"), ISODate("2024-01-01T02:00:00Z"), ..., ISODate("2024-01-01T23:00:00Z"), ISODate("2024-01-02T00:00:00Z")] lists hourly ISODate boundaries from 00:00 to 24:00, correctly defining 24 one-hour buckets.Final Answer:
[ISODate("2024-01-01T00:00:00Z"), ISODate("2024-01-01T01:00:00Z"), ISODate("2024-01-01T02:00:00Z"), ..., ISODate("2024-01-01T23:00:00Z"), ISODate("2024-01-02T00:00:00Z")] -> Option BQuick Check:
Hourly boundaries every hour for 24 hours = D [OK]
- Using half-hour or irregular intervals for hourly buckets
- Using only start and end of day as boundaries
- Using end times like 00:59:59 instead of next hour start
Ready to prove it?
Pass the test and this pattern moves unknown
