Aikasarjadatan lisääminen ja kyselyt
Oppijat lisäävät mittauseriä ja tekevät niihin kyselyitä aikaväli- ja metadatakenttien suodattimilla.
Aikasarjadatan lisääminen ja kyselyt on ilmainen MongoDB Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/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.
Mittausten lisääminen aikasarjoihin
Aikasarjakokoelmaan lisääminen käyttää täsmälleen samoja insertOne()- ja insertMany()-metodeja kuin tavallisiin kokoelmiin lisääminen. MongoDB tarkistaa timeField-kentän (jonka on oltava BSON Date) ja metaField-kentän sijoittaakseen mittauksen oikeaan sisäiseen bucketiin. Lisäys-API on tarkoituksella samanlainen, joten olemassa oleva sovelluskoodi vaatii vain vähäisiä muutoksia aikasarjakokoelmia käyttöön otettaessa.
const now = new Date()
db.sensorReadings.insertOne({
timestamp: now,
sensorId: 'sensor-42',
temperature: 23.1,
humidity: 58.4,
batteryLevel: 87
})Historiallisten tietojen massalisäys
Kun lataat historiallisia mittauksia, käytä aina mieluummin insertMany()-metodia kuin toistuvia insertOne()-kutsuja. MongoDB voi niputtaa datan bucketeihin huomattavasti tehokkaammin massatoiminnoilla. Erittäin suurissa aineistoissa (miljoonissa riveissä) kannattaa käyttää mongoimport-työkalua tai Node.js-ajurin bulkWrite()-metodia ja ryhmitellä insertOne-operaatiot 1 000–5 000 dokumentin eriin.
const readings = []
const base = new Date('2024-06-01T00:00:00Z')
for (let i = 0; i < 1440; i++) {
readings.push({
timestamp: new Date(base.getTime() + i * 60000),
sensorId: 'sensor-42',
temperature: 20 + Math.random() * 5,
humidity: 50 + Math.random() * 20
})
}
db.sensorReadings.insertMany(readings)Aikavälikyselyiden perusteet
Yleisin aikasarjadataa koskeva kyselymalli on aikavälisuodatin, joka kohdistetaan timeField-kenttään $gte- ja $lte-operaattoreilla. MongoDB käyttää sisäisten bucketien rajoja ohittaakseen kokonaiset pyydetyn aikavälin ulkopuolelle jäävät bucketit, mikä parantaa suorituskykyä huomattavasti jokaiseen dokumenttiin kohdistuvaan läpikäyntiin verrattuna. Sisällytä aikasuodatin aina suurten aikasarjakokoelmien kyselyihin.
// Last 1 hour of readings from one sensor
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000)
db.sensorReadings.find({
sensorId: 'sensor-42',
timestamp: { $gte: oneHourAgo }
}).sort({ timestamp: 1 })
// Specific day range
db.sensorReadings.find({
timestamp: {
$gte: new Date('2024-06-01T00:00:00Z'),
$lt: new Date('2024-06-02T00:00:00Z')
}
})Metatietokenttien perusteella suodattaminen
metaField-kentän perusteella suodattaminen on erittäin hyvin optimoitu — MongoDB tallentaa meta-arvon bucket-tasolla ja voi ohittaa kokonaiset muille aikasarjoille kuuluvat bucketit tutkimatta yksittäisiä mittauksia. Siksi esimerkiksi kyselyt, jotka hakevat sensor-42:n kaikki lukemat viimeisten kuuden tunnin ajalta, ovat erittäin nopeita jopa kokoelmissa, joissa on miljardeja tuhansien antureiden mittauksia.
// Query a specific device
db.sensorReadings.find({
sensorId: 'sensor-42',
timestamp: { $gte: new Date('2024-06-01T00:00:00Z') }
})
// Query multiple devices using $in on the metaField
db.sensorReadings.find({
sensorId: { $in: ['sensor-42', 'sensor-43', 'sensor-44'] },
timestamp: { $gte: new Date('2024-06-01T00:00:00Z') }
})Aikasarjojen aggregointi $match- ja $group-operaatioilla
Aggregointiputki on ensisijainen työkalu aikasarjadatan tilastojen laskemiseen. Tyypillisessä mallissa käytetään ensin $match-operaatiota aikavälin ja metaField-kentän perusteella, jotta MongoDB voi ohittaa tarpeettomat bucketit, ja sen jälkeen $group-operaatiota keskiarvojen, minimiarvojen ja maksimiarvojen laskemiseen. Sijoita $match aina ensimmäiseksi vaiheeksi, jotta bucketien karsinta voidaan ottaa käyttöön.
// Average temperature per hour for one sensor
db.sensorReadings.aggregate([
{
$match: {
sensorId: 'sensor-42',
timestamp: { $gte: new Date('2024-06-01T00:00:00Z') }
}
},
{
$group: {
_id: {
year: { $year: '$timestamp' },
month: { $month: '$timestamp' },
day: { $dayOfMonth: '$timestamp' },
hour: { $hour: '$timestamp' }
},
avgTemp: { $avg: '$temperature' },
maxTemp: { $max: '$temperature' },
minTemp: { $min: '$temperature' }
}
},
{ $sort: { '_id.hour': 1 } }
])$dateTrunc-arvon käyttäminen aikabucketeihin
$dateTrunc-aggregointilauseke (lisätty MongoDB 5.0:ssa) helpottaa mittausten ryhmittelyä kiinteän levyisiin aikaikkunoihin. Se katkaisee päivämäärän lähimpään yksikkörajaan — esimerkiksi arvon katkaiseminen arvoon 'hour' ryhmittelee saman tunnin kaikki mittaukset saman avaimen alle. Tämä korvaa monisanaisen päivämäärän eri osien poimimiseen perustuvan lähestymistavan.
// Group readings into 15-minute windows
db.sensorReadings.aggregate([
{
$match: {
sensorId: 'sensor-42',
timestamp: { $gte: new Date('2024-06-01T00:00:00Z') }
}
},
{
$group: {
_id: {
$dateTrunc: {
date: '$timestamp',
unit: 'minute',
binSize: 15
}
},
avgTemp: { $avg: '$temperature' },
count: { $sum: 1 }
}
},
{ $sort: { _id: 1 } }
])Aikasarjatulosten projisointi
Käytä projektiota rajoittamaan aikasarjakyselyistä palautettavia kenttiä aivan kuten tavallisissa kokoelmissa. Vain tarvittavien kenttien projisointi vähentää verkkosiirron määrää ja asiakkaan muistinkulutusta. Huomaa, että timeField- ja metaField-kentät ovat aina käytettävissä projisointiin ja _id-kentän voi piilottaa arvolla _id: 0.
// Return only timestamp and temperature
db.sensorReadings.find(
{
sensorId: 'sensor-42',
timestamp: { $gte: new Date('2024-06-01T08:00:00Z') }
},
{
_id: 0,
timestamp: 1,
temperature: 1
}
).sort({ timestamp: 1 })Mittausten laskeminen ja otanta
Laske aikavälin mittaukset käyttämällä countDocuments()-metodia suodattimen kanssa. Suurissa kokoelmissa estimatedDocumentCount() antaa nopean likimääräisen kokonaismäärän kokoelman metatietojen perusteella. Kun korjaat virheitä tai rakennat koontinäyttöjä, aggregointiputken $sample-operaatiolla voit hakea satunnaisen osajoukon mittauksista ilman koko tulosjoukon läpikäyntiä.
// Count readings in last 24 hours
const since = new Date(Date.now() - 86400000)
db.sensorReadings.countDocuments({
sensorId: 'sensor-42',
timestamp: { $gte: since }
})
// Random sample of 10 recent measurements
db.sensorReadings.aggregate([
{ $match: { timestamp: { $gte: since } } },
{ $sample: { size: 10 } }
])Node.js-ajuri: aikasarjadatan lukeminen
Node.js-sovelluksessa aikasarjakokoelmien kyselyt tehdään samalla tavalla kuin tavallisten kokoelmien kyselyt. Käytä kokoelmaobjektin tavallisia find()- tai aggregate()-metodeja. Koska aikasarjakyselyt palauttavat usein suuria tulosjoukkoja, käytä kursorin kanssa async-iteraatiota sen sijaan, että lataisit kaiken muistiin toArray()-metodilla.
const { MongoClient } = require('mongodb')
async function getRecentReadings(client) {
const db = client.db('iot')
const col = db.collection('sensorReadings')
const since = new Date(Date.now() - 3600000) // last hour
const cursor = col.find(
{ sensorId: 'sensor-42', timestamp: { $gte: since } },
{ projection: { _id: 0, timestamp: 1, temperature: 1 } }
).sort({ timestamp: 1 })
for await (const doc of cursor) {
console.log(doc.timestamp, doc.temperature)
}
}Suorituskyky: miksi aikaväli käsitellään ensin
Aikasarjadatan kyselyiden tärkein sääntö on: suodata aina aikavälin perusteella ennen muita ehtoja. MongoDB:n bucketien karsinta aktivoituu vain, kun timeField-kentän suodatin sisältyy kyselyyn. Ilman sitä MongoDB joutuu käymään läpi jokaisen bucketin. Yhdistä lisäksi aikasuodatin metaField-suodattimeen, jotta voit hyödyntää molempia bucketien ohitusmenetelmiä — aikarajoja ja aikasarjan tunnistetta.
// GOOD: time + meta filter — fast bucket pruning
db.sensorReadings.find({
sensorId: 'sensor-42', // prune by series
timestamp: { $gte: since }, // prune by time
temperature: { $gt: 30 } // measurement filter applied after pruning
})
// BAD: no time filter — scans all buckets
db.sensorReadings.find({
temperature: { $gt: 30 } // forces full scan
})Bucketien käyttöasteen seuranta
Voit tarkastella sisäisiä bucket-dokumentteja järjestelmän nimiavaruuden kautta: system.buckets.<collectionName>. Vaikka tähän nimiavaruuteen ei voi kirjoittaa suoraan, sen lukeminen paljastaa bucketien määrän ja sen, kuinka monta mittausta kukin bucket sisältää. Tämä on hyödyllistä granularity-asetusta säädettäessä — ihannetapauksessa jokaisen bucketin tulisi olla lähellä enimmäistäyttöastetta (3 600 mittausta 'seconds'-granularitylla).
// Count internal bucket documents
db['system.buckets.sensorReadings'].countDocuments()
// Inspect a sample bucket (internal format)
db['system.buckets.sensorReadings'].findOne()Pikatarkistus
Testaa ymmärryksesi tämän oppitunnin MongoDB- ja NoSQL-tietokantoja koskevista käsitteistä.
Oppitunnin yhteenveto
Tässä oppitunnissa opit, että insertMany() erissä käytettynä on tehokas tapa ladata aikasarjadataa, timeField- ja metaField-kenttien perusteella yhdessä suodattaminen mahdollistaa bucketien karsimisen nopeissa aikavälikyselyissä ja $dateTrunc aggregointiputkissa helpottaa mittausten ryhmittelyä kiinteän levyisiin aikaikkunoihin. Seuraavaksi tutustumme aikasarjojen ikkuna-aggregointeihin $setWindowFields-operaation avulla.
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 ”Aikasarjadatan lisääminen ja kyselyt” ilmainen?
Kyllä – oppitunnin ”Aikasarjadatan lisääminen ja kyselyt” 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 ”Aikasarjadatan lisääminen ja kyselyt”?
Oppijat lisäävät mittauseriä ja tekevät niihin kyselyitä aikaväli- ja metadatakenttien suodattimilla. 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 2/4.
Kuinka kauan ”Aikasarjadatan lisääminen ja kyselyt”-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
- Aikasarjakokoelman luominen
- Aikasarjadatan lisääminen ja kyselyt
- Ikkunakoostaminen aikasarjoille
- Datan automaattinen vanhentaminen expireAfterSeconds-asetuksella