Data sensor tumbuh tanpa batas, tetapi nilai informasinya tidak: rata-rata per jam bulan lalu tetap berharga, sementara pengukuran mentah per 30 menit dari dua tahun lalu jarang dibaca siapa pun. Retensi adalah keputusan tentang umur data — dan di time series collection, MongoDB menyediakan dua mekanisme pelengkapnya: TTL untuk menghapus data lawas secara otomatis, dan $merge untuk meninggalkan ringkasan. Bagian penutup ini memasang keduanya, membuktikan TTL benar-benar bekerja, lalu menutup proyek dengan bukti performa dan suite tes.
Skrip Retensi #
retensi.js melakukan tiga hal: memasang lalu melepas TTL pada collection utama (dataset kita historis — TTL 7 hari akan menghapus semuanya), membuktikan TTL nyata pada collection uji kecil, dan membangkitkan ringkasan harian:
Jalankan (skrip menunggu 70 detik untuk siklus TTL — itu memang bagian dari pembuktian):
mongosh "mongodb://127.0.0.1:27017/?directConnection=true" --file src/retensi.jsOutput yang Dihasilkan (metadata $clusterTime dipangkas agar ringkas):
== collMod: pasang expireAfterSeconds 604800 (7 hari) ==
{ ok: 1 }
opsi collection sekarang:
{
expireAfterSeconds: Long('604800'),
timeseries: {
timeField: 'ts',
metaField: 'sensor',
granularity: 'minutes',
bucketMaxSpanSeconds: 86400,
fixedBucketing: true
}
}
== collMod: matikan TTL (expireAfterSeconds "off") ==
{ ok: 1 }
== uji TTL nyata pada sensor_tes_ttl ==
{ ok: 1 }
titik sebelum TTL: 2
menunggu 70 detik (TTL monitor berjalan tiap 60 detik)...
titik setelah TTL : 0
== downsampling: ringkasan per sensor per hari ($merge) ==
baris ringkasan: 12
2026-01-01 BDG-07 Bandung rata 25.78 °C maks 27.5 °C | 48 titik
2026-01-01 JKT-01 Jakarta rata 28.88 °C maks 30.5 °C | 48 titik
2026-01-02 SBY-12 Surabaya rata 31.01 °C maks 32.8 °C | 48 titik
...
2026-01-03 YOG-03 Yogyakarta rata 27.89 °C maks 30 °C | 29 titikTiga temuan penting dari keluaran ini:
collModmenerimaexpireAfterSeconds: "off"— TTL bisa dilepas tanpa menghapus collection. Perhatikan juga mengapa TTL dilepas lagi: dataset kita bertanggal Januari 2026; dengan TTL 7 hari, seluruhnya kedaluwarsa dan akan terhapus pada siklus monitor berikutnya.- TTL terbukti nyata: collection uji diisi dua titik ber-timestamp 26 jam lalu,
collModmemasang TTL 30 detik, dan setelah menunggu satu siklus monitor (berjalan tiap 60 detik) jumlah titik menjadi 0. TTL pada time series bekerja di level bucket — bucket yang seluruh isinya lawas dihapus utuh. - Downsampling menghasilkan 12 baris: 4 sensor × 3 hari, dengan
whenMatched: "replace"menjadikan skrip aman diulang — ringkasan selalu yang termutakhir.
Bukti Performa #
uji-performa.js membandingkan empat query pada explain("executionStats") dan menutup dengan perbandingan working set:
Output yang Dihasilkan (bagian winningPlan ringkas — CLUSTERED_IXSCAN pertama menampilkan bentuk lengkapnya):
== JKT-01 sepanjang 1 Januari ==
{
isCached: false,
stage: 'CLUSTERED_IXSCAN',
filter: { ... filter pada meta.sensor_id dan control.min/max/ts ... },
nss: 'proyek_sensor.sensor_cuaca',
direction: 'forward'
}
bucket cocok : 1 | kunci diperiksa: 2 | bucket diperiksa: 5
pengukuran keluar: Long('48')
== JKT-01 tanpa rentang waktu ==
bucket cocok : 3 | kunci diperiksa: 0 | bucket diperiksa: 12
pengukuran keluar: Long('125')
== tanpa filter ==
bucket cocok : 12 | kunci diperiksa: 0 | bucket diperiksa: 12
pengukuran keluar: Long('500')
== index otomatis sensor_1_ts_1 ==
bucket cocok : 1 | kunci diperiksa: 2 | bucket diperiksa: 1
pengukuran keluar: Long('48')
== perbandingan working set ==
sensor_cuaca : 500 pengukuran | 12 bucket | data 6524 byte | terpakai 20480 byte
ringkasan_harian: 12 baris | data 1684 byte | terpakai 36864 byteEmpat baris “bucket cocok” itu menceritakan satu kisah:
- Sensor + rentang waktu (kunci diperiksa 2, bucket diperiksa 5): filter sensor memangkas lewat index otomatis, lalu rentang waktu menyaring bucket — 48 pengukuran keluar tanpa perlu menyentuh data lain.
- Sensor tanpa rentang (bucket diperiksa 12): tanpa batas waktu, seluruh 12 bucket harus dibuka meski hasilnya hanya 3 bucket milik sensor itu.
- Tanpa filter (semuanya diperiksa): tidak ada jalan lain — semua data keluar.
- Filter meta bentuk penuh (bucket diperiksa 1): saat filter
sensorditulis sebagai subdocument lengkap{ kota, sensor_id }sesuai urutan tersimpan, index otomatis bekerja paling rapat — satu bucket, dua kunci.
Perbandingan working set menutup argumen retensi: 500 pengukuran mentah (6,5 KB data) direduksi menjadi 12 baris ringkasan (1,7 KB). Pada skala nyata rasio ini yang menjaga dashboard tahunan tetap cepat — kita membaca ringkasan, bukan miliaran titik mentah.
Suite Tes Penutup #
Suite ini menyiapkan datanya sendiri di database proyek_sensor_tes — termasuk mereplikasi generator deterministik untuk membandingkan rata-rata hasil server dengan hitungan lokal:
mongosh "mongodb://127.0.0.1:27017/?directConnection=true" --file tests/semua-tes.jsOutput yang Dihasilkan:
lulus - collection bertipe timeseries
lulus - timeField = ts
lulus - metaField = sensor
lulus - index otomatis sensor_1_ts_1 terpasang
lulus - total 500 pengukuran
lulus - 125 titik untuk SBY-12
lulus - field ts berupa Date
lulus - metaField sensor tersimpan
lulus - kota pada metaField benar
lulus - suhu numerik
lulus - kelembapan numerik
lulus - rata-rata suhu server = hitungan lokal (28.4608)
lulus - JKT-01 pada 1 Januari = 48 titik (interval 30 menit)
lulus - 24 kelompok jam pada 1 Januari
lulus - setiap jam berisi tepat 2 titik
lulus - ringkasan harian = 12 baris
lulus - 8 baris berisi 48 titik (2 hari penuh x 4 sensor)
lulus - collMod expireAfterSeconds diterima
lulus - opsi TTL tersimpan
lulus - TTL dapat dimatikan kembali
SEMUA TES LULUSDengan ini proyek — dan seluruh Course MongoDB — tuntas: data time series dari schema, penyimpanan, analisis, sampai retensi, semuanya berjalan dan teruji. Selamat menyelesaikan perjalanan panjangnya.