Mönstren Bucket och Computed
Ni kommer att gruppera tidsseriedata i bucket-dokument för att minska indexstorleken och beräkna aggregerade värden i förväg för att undvika kostsamma realtidsberäkningar.
Mönstren Bucket och Computed är en gratis lektion i MongoDB Academy på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för MongoDB Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i MongoDB Academy innehåller totalt 4 lektioner.
Introduktion till mönster för schemadesign
Erfarna MongoDB-utvecklare utformar inte scheman på känsla — de använder ett bibliotek med beprövade mönster som löser återkommande utmaningar. Dessa mönster bygger på svårvunna lärdomar om hur MongoDB:s lagringsmotor, indexstruktur och aggregeringspipeline samverkar med olika dokumentstrukturer. Bucket Pattern och Computed Pattern är två av de mest betydelsefulla mönstren för prestandakänsliga applikationer.
Problemet: för många små dokument
Föreställ Er ett IoT-system där varje sensormätning är ett separat dokument. En sensor som producerar en mätning per sekund genererar 86 400 dokument per dag. Det innebär 86 400 indexposter per sensor och dag, enorma indexstorlekar och ett stort antal åtgärder när dagens data ska frågas ut. Att läsa 24 timmars data kräver att tiotusentals små dokument hämtas — mycket ineffektivt.
// Anti-pattern: one document per reading
{
_id: ObjectId(),
sensorId: 'sensor-42',
timestamp: ISODate('2024-06-01T10:00:01Z'),
temperature: 23.1
}
// 86,400 such documents per sensor per day
// 86,400 index entries per sensor per dayBucket Pattern: gruppera i buckets
Bucket Pattern grupperar relaterade små dokument i ett enda större dokument (en ”bucket”). I stället för ett dokument per mätning innehåller ett dokument en timmes mätningar — vilket minskar 3 600 dokument till 1 och 3 600 indexposter till 1. Bucket-dokumentet innehåller en array med mätningar samt sammanfattande statistik som beräknas vid skrivningen. Detta minskar indexstorleken drastiskt och förbättrar prestandan för intervallfrågor.
// Bucket Pattern: one document per sensor per hour
{
_id: ObjectId(),
sensorId: 'sensor-42',
date: ISODate('2024-06-01T10:00:00Z'), // hour bucket boundary
count: 3600,
measurements: [
{ ts: ISODate('2024-06-01T10:00:01Z'), temp: 23.1 },
{ ts: ISODate('2024-06-01T10:00:02Z'), temp: 23.2 },
// ... 3598 more readings ...
],
// Pre-computed summaries
avgTemp: 23.15,
maxTemp: 24.1,
minTemp: 22.8
}Lägga till i en bucket med $push och $inc
När ett nytt mätvärde kommer in hittar du det aktuella bucket-dokumentet för sensorn och timmen och uppdaterar det atomiskt med $push för att lägga till värdet i mätvärdesarrayen och $inc för att öka antalet. Använd upsert: true så att MongoDB skapar ett nytt bucket-dokument om bucketen för den aktuella timmen ännu inte finns.
const now = new Date()
const hourBucket = new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours())
db.sensorBuckets.updateOne(
{
sensorId: 'sensor-42',
date: hourBucket,
count: { $lt: 3600 } // don't overfill a bucket
},
{
$push: { measurements: { ts: now, temp: 23.5 } },
$inc: { count: 1 },
$min: { minTemp: 23.5 },
$max: { maxTemp: 23.5 }
},
{ upsert: true }
)Fråga över flera bucketer
Om du vill hämta alla avläsningar för en sensor under ett tidsintervall frågar du bucket-dokumenten med hjälp av sensorId och intervallet för date. Använd sedan antingen de förberäknade sammanfattningarna för aggregerade resultat eller $unwind på mätvärdesarrayen för att komma åt enskilda avläsningar. Att fråga efter 24 timmars data innebär nu att 24 bucket-dokument läses i stället för 86 400 enskilda dokument – en 3 600-faldig minskning av antalet hämtade dokument.
// Get hourly summaries for a day (reads 24 bucket docs)
db.sensorBuckets.find(
{
sensorId: 'sensor-42',
date: {
$gte: ISODate('2024-06-01T00:00:00Z'),
$lt: ISODate('2024-06-02T00:00:00Z')
}
},
{ _id: 0, date: 1, avgTemp: 1, maxTemp: 1, minTemp: 1, count: 1 }
).sort({ date: 1 })Computed-mönstret: förberäkna resultat
Computed-mönstret beräknar kostsamma aggregeringar i samband med skrivning och lagrar resultatet direkt i dokumentet. I stället för att beräkna ett genomsnittligt betyg för en produkt genom att summera alla recensioner vid läsningstillfället, beräknar du det varje gång en ny recension läggs till och lagrar avgRating tillsammans med reviewCount i produktdokumentet. Läsningar blir då mycket billiga – returnera bara det förberäknade fältet.
// Product document with pre-computed stats
{
_id: ObjectId(),
name: 'Wireless Headphones',
price: 149.99,
// Pre-computed at write time
reviewCount: 1247,
avgRating: 4.3,
ratingSum: 5362.1 // stored to recompute avg without fetching all reviews
}Uppdatera beräknade fält inkrementellt
När en ny recension kommer in uppdaterar du de beräknade fälten atomiskt i samma operation i stället för att beräkna om dem från början. Öka reviewCount och ratingSum med $inc och beräkna sedan om avgRating. I MongoDB kan du göra detta med en uppdatering i pipeline-stil (MongoDB 4.2+) som använder $divide för att ange genomsnittet utifrån det uppdaterade antalet och summan.
// Atomic incremental update of computed stats
db.products.updateOne(
{ _id: productId },
[
{
$set: {
reviewCount: { $add: ['$reviewCount', 1] },
ratingSum: { $add: ['$ratingSum', newRating] }
}
},
{
$set: {
avgRating: { $divide: ['$ratingSum', '$reviewCount'] }
}
}
]
)När Computed-mönstret ska användas
Computed-mönstret är mest värdefullt när läsningar är betydligt fler än skrivningar och beräkningen skulle vara kostsam vid läsningstillfället. Genomsnittliga produktbetyg, poäng på topplistor, antal visningar av artiklar och intäktssummor är alla utmärkta användningsområden. Avvägningen är något mer komplexa skrivningar och behovet av att hålla de beräknade värdena konsekventa när källdata ändras. Om både läsningar och skrivningar sker ofta kan du överväga bakgrundsjobb som beräknar om värdena regelbundet i stället för synkrona uppdateringar.
Kombinera båda mönstren
Bucket-mönstret och Computed-mönstret används ofta tillsammans. Ett system för sensordata kan gruppera avläsningar i bucket-dokument per timme (Bucket-mönstret) och underhålla ett förberäknat dagligt sammanfattningsdokument (Computed-mönstret) som lagrar min/max/avg för hela dagen. Med denna hierarkiska metod behöver instrumentpaneler som visar dagliga trender bara läsa ett enda dokument, medan detaljfrågor bara behöver söka igenom 24 bucket-dokument per timme.
// Daily summary document (Computed Pattern on top of Bucket Pattern)
{
_id: ObjectId(),
sensorId: 'sensor-42',
date: ISODate('2024-06-01T00:00:00Z'),
totalReadings: 86400,
dailyAvgTemp: 22.8,
dailyMaxTemp: 28.4,
dailyMinTemp: 18.2,
peakHour: 14 // hour with highest average temperature
}Avvägningar kring bucketstorlek
Bucket-dokument bör inte växa obegränsat – MongoDB har en gräns på 16 MB per dokument. För sensorer med hög datahastighet använder du tidsbegränsade bucketer, till exempel en per timme eller dag. Villkoret count: { $lt: 3600 } i uppdateringsfiltret förhindrar att bucketen överfylls. Om en bucket når sin kapacitet skapar upsert automatiskt en ny bucket. Övervaka hur snabbt bucketer fylls i produktion och anpassa bucketstorleken efter din datahastighet.
Bucket-mönstrets påverkan på index
Det primära indexet i en bucket-samling bör täcka frågemönstret: { sensorId: 1, date: 1 }. Detta sammansatta index innebär att frågor som filtrerar på sensor och tidsintervall går direkt mot indexet. Om du jämför med att indexera fältet timestamp i 86 400 enskilda dokument innehåller bucket-samlingens index bara 24 poster per sensor och dag – en 3 600-faldig minskning av indexstorleken som avsevärt förbättrar möjligheten att hålla arbetsmängden i RAM.
// Create supporting index for bucket pattern queries
db.sensorBuckets.createIndex({ sensorId: 1, date: 1 })
// Explain query to verify IXSCAN usage
db.sensorBuckets.find({ sensorId: 'sensor-42', date: { $gte: ISODate('2024-06-01T00:00:00Z') } }).explain('executionStats')Snabbtest
Testa dina kunskaper om begreppen MongoDB och NoSQL Databases från den här lektionen.
Sammanfattning av lektionen
I den här lektionen lärde du dig att Bucket-mönstret grupperar många små dokument till färre och större dokument, vilket kraftigt minskar indexstorleken och förbättrar prestandan för intervallfrågor, att Computed-mönstret förberäknar kostsamma aggregeringar vid skrivning så att läsningar direkt kan returnera lagrade värden, och att de två mönstren kombineras effektivt i tidsseriepipelines med flera nivåer. Härnäst utforskar vi Extended Reference- och Subset-mönstren.
Lär dig JavaScript med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 30
- Lektioner
- 120
Vanliga frågor
Är lektionen ”Mönstren Bucket och Computed” gratis?
Ja – hela texten till ”Mönstren Bucket och Computed” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i MongoDB Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i MongoDB Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Mönstren Bucket och Computed”?
Ni kommer att gruppera tidsseriedata i bucket-dokument för att minska indexstorleken och beräkna aggregerade värden i förväg för att undvika kostsamma realtidsberäkningar. Ni övar på MongoDB Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig MongoDB Academy?
Du behöver inga förkunskaper. Utbildningen i MongoDB Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”Mönstren Bucket och Computed”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här MongoDB Academy-lektionen?
Ja. Varje MongoDB Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Mönstren Bucket och Computed
- Mönstren Extended Reference och Subset
- Mönstren Polymorphic och Schema Versioning
- Mönstren Outlier och Tree Structure