Empat sensor cuaca, satu titik data tiap tiga puluh menit, tanpa jeda: dalam sebulan saja terkumpul hampir 6.000 pengukuran per sensor. Menyimpannya di collection biasa terasa sah — insert-nya pun sama saja — tetapi kita kehilangan tiga keuntungan besar time series collection: pengelompokan otomatis titik-titik data ke dalam bucket yang terkompresi, index otomatis pada pasangan meta-waktu, dan dukungan penuh operator analisis waktu. Bagian ini merancang fondasinya: satu collection sensor_cuaca dengan metaField yang tepat, lalu memverifikasi bahwa MongoDB benar-benar memperlakukannya sebagai time series.
Keputusan Desain: MetaField dan Granularity #
Dua keputusan menentukan kualitas seluruh proyek ini, dan keduanya harus diambil sekarang.
Keputusan pertama: apa yang menjadi metaField. Isi field inilah identitas seri data — nilai yang sama dari satu pengukuran ke pengukuran berikutnya. Untuk sensor cuaca, identitas seri adalah sensornya sendiri: sensor_id dan kota. MongoDB mengelompokkan pengukuran dari meta yang sama ke dalam satu bucket, jadi meta yang stabil membuat bucket padat dan kompresi maksimal. Kebalikannya, nilai yang berubah tiap titik (suhu, kelembapan) wajib berada di luar metaField — kalau masuk, setiap pengukuran membangun bucket sendiri dan keuntungan pengelompokan menguap.
Keputusan kedua: granularity. Opsi ini memberi tahu MongoDB seberapa rapat titik data datang — "seconds", "minutes", atau "hours" — dan dipakai untuk mengoptimalkan jendela internal bucket. Sensor kita menulis tiap 30 menit, sehingga "minutes" adalah pilihan yang tepat.
Skrip buat-collection.js merangkai semuanya:
Jalankan dari folder proyek:
mongosh "mongodb://127.0.0.1:27017/?directConnection=true" --file src/buat-collection.jsOutput yang Dihasilkan:
database direset: proyek_sensor
== membuat collection sensor_cuaca ==
{ ok: 1 }
== verifikasi tipe collection ==
name : sensor_cuaca
type : timeseries
{
timeseries: {
timeField: 'ts',
metaField: 'sensor',
granularity: 'minutes',
bucketMaxSpanSeconds: 86400,
fixedBucketing: true
}
}
== index yang terpasang ==
sensor_1_ts_1 -> {"sensor":1,"ts":1}Mari kita bedah keluarannya:
type: 'timeseries':getCollectionInfos()mengonfirmasi collection ini bukan collection biasa — kita tidak membuatnya lewat insert pertama, melainkancreateCollectiondengan opsitimeseries.bucketMaxSpanSeconds: 86400: satu bucket menampung pengukuran dari satu sensor maksimal sepanjang 24 jam — nilai yang diturunkan otomatis darigranularity: "minutes".sensor_1_ts_1: index majemuk{ sensor: 1, ts: 1 }terpasang tanpa kita minta. Inilah index otomatis time series: meta di depan, waktu di belakang — persis bentuk yang dibutuhkan query “sensor ini, rentang waktu ini”.
Kenapa Bukan Collection Biasa #
Perbandingan singkat memperjelas posisi kita:
| Aspek | Collection biasa | Time series collection |
|---|---|---|
| Index pertama | Harus dibuat manual | { meta, time } otomatis |
| Penyimpanan | Satu document per pengukuran | Bucket terkompresi per sensor |
| Update/delete | Bebas | Terbatas (data historis memang jarang diubah) |
_id per pengukuran | Dikelola sendiri | Muncul otomatis di hasil baca, tidak kita tulis |
| Cocok untuk | Data transaksional yang berubah | Data urut waktu yang append-only |
Baris _id layak diperhatikan: pada time series kita tidak menulis _id sendiri — MongoDB menyediakannya pada hasil pembacaan, dan kita tidak mengandalkannya sebagai kunci data. Identitas satu pengukuran adalah pasangan sensor + ts.
Dengan collection siap, Bagian 2 mengisinya: 500 pengukuran deterministik yang menjadi bahan analisis seluruh proyek.