MongoDB Academy · Oppitunti

Bucket- ja Computed-mallit

Ryhmittelette aikasarjatiedot bucket-dokumenteiksi indeksien koon pienentämiseksi ja laskette koostetut arvot etukäteen reaaliaikaisten, raskaiden laskutoimitusten välttämiseksi.

Oppitunti 1/413 vaihetta

Bucket- ja Computed-mallit on ilmainen MongoDB Academy-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu MongoDB Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. MongoDB Academy-kurssilla on yhteensä 4 oppituntia.

Johdatus skeemansuunnittelumalleihin

Kokeneet MongoDB-insinöörit eivät suunnittele skeemoja vaistonvaraisesti — he hyödyntävät todennettujen mallien kirjastoa, joka ratkaisee toistuvia haasteita. Näihin malleihin on koottu opit siitä, miten MongoDB:n tallennusmoottori, indeksirakenne ja aggregointiputki toimivat yhdessä erilaisten dokumenttirakenteiden kanssa. Bucket Pattern ja Computed Pattern ovat suorituskykykriittisissä sovelluksissa kaksi vaikuttavinta mallia.

Ongelma: liikaa pieniä dokumentteja

Ajatellaan IoT-järjestelmää, jossa jokainen anturilukema on erillinen dokumentti. Yhden lukeman sekunnissa tuottava anturi luo 86 400 dokumenttia päivässä. Tämä tarkoittaa 86 400 indeksimerkintää anturia kohden päivässä, valtavaa indeksikokoa ja suurta määrää operaatioita päivän tietojen kyselyssä. Vuorokauden tietojen lukeminen edellyttää kymmenientuhansien pienten dokumenttien hakemista — erittäin tehotonta.

// 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 day

Bucket Pattern: ryhmittely säiliöihin

Bucket Pattern ryhmittelee toisiinsa liittyvät pienet dokumentit yhdeksi suuremmaksi dokumentiksi (”säiliöksi”). Yhden lukeman sijaan dokumentti sisältää yhden tunnin lukemat — näin 3 600 dokumenttia vähenee yhdeksi ja 3 600 indeksimerkintää yhdeksi. Säiliödokumentti sisältää mittausten taulukon sekä kirjoitushetkellä lasketut yhteenvetotilastot. Tämä pienentää indeksin kokoa huomattavasti ja parantaa aluekyselyjen suorituskykyä.

// 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
}

Tietojen lisääminen säilöön komennoilla $push ja $inc

Kun uusi mittaus saapuu, etsi anturin ja tunnin nykyinen säilöasiakirja ja päivitä se atomisesti käyttämällä komentoa $push mittauksen lisäämiseen measurements-taulukkoon ja komentoa $inc lukumäärän kasvattamiseen. Käytä asetusta upsert: true, jotta MongoDB luo uuden säilöasiakirjan, jos kuluvan tunnin säilöä ei vielä ole.

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 }
)

Kyselyt useiden säilöjen yli

Kun haluat hakea kaikki anturin lukemat tietyltä aikaväliltä, tee säilöasiakirjoihin kysely kenttien sensorId ja date aikavälin perusteella. Käytä joko valmiiksi laskettuja yhteenvetoja koontituloksiin tai pura measurements-taulukko komennolla $unwind, jos tarvitset yksittäiset lukemat. Nyt 24 tunnin tietojen kysely lukee 24 säilöasiakirjaa 86 400 yksittäisen asiakirjan sijaan — haettavien asiakirjojen määrä vähenee 3 600-kertaisesti.

// 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-malli: tulosten laskeminen etukäteen

Computed-malli laskee raskaat koonnit etukäteen kirjoitushetkellä ja tallentaa tuloksen suoraan asiakirjaan. Sen sijaan että tuotteen keskimääräinen arvosana laskettaisiin lukemisen yhteydessä kaikkia arvosteluja summaamalla, laske se aina uuden arvostelun lisäämisen yhteydessä ja tallenna avgRating sekä reviewCount tuotteen asiakirjaan. Lukeminen on tällöin erittäin edullista — palauta vain etukäteen laskettu kenttä.

// 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
}

Laskettujen kenttien päivittäminen asteittain

Kun uusi arvostelu saapuu, päivitä lasketut kentät atomisesti saman operaation aikana sen sijaan, että laskisit kaiken uudelleen alusta alkaen. Kasvata kenttiä reviewCount ja ratingSum komennolla $inc ja laske sitten avgRating uudelleen. MongoDB:ssä tämä onnistuu putkityylisellä päivityksellä (MongoDB 4.2 tai uudempi), jossa komennolla $divide asetetaan keskiarvo päivitetyn lukumäärän ja summan perusteella.

// 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'] }
      }
    }
  ]
)

Milloin Computed-mallia kannattaa käyttää

Computed-malli on hyödyllisin, kun lukukertoja on huomattavasti enemmän kuin kirjoituskertoja ja laskenta olisi kallista lukuhetkellä. Tuotteiden arvosanojen keskiarvot, tulostaulukoiden pisteet, artikkelien katselukerrat ja liikevaihdon kokonaissummat ovat kaikki erinomaisia käyttökohteita. Vastineeksi kirjoituslogiikka monimutkaistuu hieman, ja laskettujen arvojen johdonmukaisuus on säilytettävä lähdetietojen muuttuessa. Jos sekä luku- että kirjoitusoperaatioita tehdään usein, harkitse säännöllisesti suoritettavia taustatöitä synkronisten päivitysten sijaan.

Molempien mallien yhdistäminen

Bucket- ja Computed-malleja käytetään usein yhdessä. Anturitietojärjestelmä voi ryhmitellä lukemat tunneittain säilöasiakirjoihin (Bucket-malli) ja ylläpitää etukäteen laskettua päivittäistä yhteenvetoasiakirjaa (Computed-malli), joka tallentaa koko päivän pienimmän, suurimman ja keskimääräisen arvon. Tämän porrastetun lähestymistavan ansiosta päivittäisiä trendejä näyttävä koontinäyttö lukee vain yhden asiakirjan, kun taas tarkemmat kyselyt käyvät läpi vain 24 tunnin säilöasiakirjaa.

// 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
}

Säilön koon kompromissit

Säilöasiakirjojen ei pidä kasvaa rajattomasti — MongoDB:n asiakirjakoko on enintään 16 Mt. Käytä paljon tietoa tuottaville antureille aikaan rajattuja säilöjä, esimerkiksi yhtä tunnissa tai päivässä. Päivityssuodattimen ehto count: { $lt: 3600 } estää säilön ylitäyttymisen. Kun säilö saavuttaa kapasiteettinsa, upsert luo automaattisesti uuden säilön. Seuraa tuotannossa säilöjen täyttöastetta ja säädä säilön koko tietojesi nopeudelle sopivaksi.

Bucket-mallin vaikutus indekseihin

Säilökokoelman ensisijaisen indeksin pitäisi vastata kyselymallia: { sensorId: 1, date: 1 }. Tämä yhdistelmäindeksi tarkoittaa, että anturin ja aikavälin perusteella suodatettavat kyselyt osuvat suoraan indeksiin. Kun verrataan 86 400 yksittäisen asiakirjan timestamp-kentän indeksointiin, säilökokoelman indeksissä on vain 24 tietuetta anturia ja päivää kohden — indeksin koko pienenee 3 600-kertaisesti, mikä parantaa huomattavasti työjoukon mahtumista RAM-muistiin.

// 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')

Pikatesti

Testaa, miten hyvin ymmärrät tämän oppitunnin MongoDB- ja NoSQL-tietokantoja koskevat käsitteet.

Oppitunnin kertaus

Tässä oppitunnissa opit, että Bucket-malli ryhmittelee monia pieniä asiakirjoja harvemmiksi suuremmiksi asiakirjoiksi, mikä pienentää indeksin kokoa huomattavasti ja parantaa aikavälikyselyjen suorituskykyä, Computed-malli laskee raskaat koonnit etukäteen kirjoitushetkellä, jolloin lukutoiminnot palauttavat valmiiksi tallennetut arvot välittömästi, ja nämä kaksi mallia toimivat tehokkaasti yhdessä monitasoisissa aikasarjaputkissa. Seuraavaksi tutustumme Extended Reference- ja Subset-malleihin.

Aloita maksutta

Opi JavaScript tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
30
Oppitunnit
120

Usein kysytyt kysymykset

Onko oppitunti ”Bucket- ja Computed-mallit” ilmainen?

Kyllä – oppitunnin ”Bucket- ja Computed-mallit” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko MongoDB Academy-kurssin, päivitä CoddyKit PROhon. MongoDB Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Bucket- ja Computed-mallit”?

Ryhmittelette aikasarjatiedot bucket-dokumenteiksi indeksien koon pienentämiseksi ja laskette koostetut arvot etukäteen reaaliaikaisten, raskaiden laskutoimitusten välttämiseksi. Harjoittelet MongoDB Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni MongoDB Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin MongoDB Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.

Kuinka kauan ”Bucket- ja Computed-mallit”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä MongoDB Academy-oppitunnilla?

Kyllä. Jokainen MongoDB Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Bucket- ja Computed-mallit
  2. Extended Reference- ja Subset-mallit
  3. Polymorphic- ja Schema Versioning -mallit
  4. Outlier- ja Tree Structure -mallit
← Takaisin: MongoDB Academy