Setelah bertahun-tahun melihat desain skema yang berhasil di production, komunitas MongoDB merangkum solusi yang berulang menjadi kumpulan pola bernama — dipublikasikan lewat seri blog resmi “Building with Patterns”. Pola bekerja seperti kosakata bersama: daripada menjelaskan “simpan sebagian data panas di document utama”, cukup sebut “Subset Pattern” dan tim langsung paham trade-off-nya. Chapter ini memetakan sembilan pola resmi, lalu menguji tiga di antaranya yang belum punya chapter sendiri; enam sisanya dibahas tuntas di chapter-chapter sekitarnya.
Peta Sembilan Pola #
| Pola | Inti | Kapan dipakai | Bab detail |
|---|---|---|---|
| Attribute | Field langka/beragam dipecah menjadi pasangan k–v dalam array | Field bervariasi antar document, query perlu satu index lintas atribut | Bab ini |
| Bucket | Data deret waktu dikelompokkan per rentang (menit/jam) | Sensor, log, metrik berfrekuensi tinggi | Bucket Pattern |
| Computed | Hasil perhitungan disimpan di document | Agregasi mahal yang dibaca berulang (rata-rata, total) | Computed Pattern |
| Extended Reference | Sebagian field yang sering dibaca disalin dari document rujukan | Duplikasi kecil demi menghindari $lookup di jalur panas | Bab ini |
| Outlier | Entitas ekstrem dipisah representasinya | 1% data dengan skala ratusan kali dari populasi umum | Outlier Pattern |
| Polymorphic | Banyak bentuk document dalam satu collection dengan field pembeda | Entitas sejenis dengan variasi field | Polymorphic Pattern |
| Schema Versioning | Field schemaVersion menandai bentuk document | Migrasi bertahap tanpa henti layanan | Bab ini |
| Subset | Hanya subset data panas yang embed di induk | Array besar yang hanya ujungnya yang dibaca | Subset Pattern |
| Approximate Quantification | Counter diperbarui sebagian, nilainya kira-kira | Statistik yang tak harus exact (jumlah views) | Bab ini |
Tiga baris terakhir yang berlabel “Bab ini” kita praktikkan sekarang; enam lainnya cukup dibuka chapter-nya masing-masing.
Attribute Pattern #
Produk toko buku punya atribut yang tidak seragam: buku punya tebalHalaman, mainan edukatif punya usiaMinimum, e-reader punya kapasitasGB. Membuat field terpisah untuk semuanya menghasilkan document jarang terisi dan butuh banyak index. Attribute Pattern memecahnya menjadi array pasangan k–v:
use latihan_modeling
db.dropDatabase()
db.produk.insertMany([
{ _id: 1, nama: "Buku Bumi", atribut: [ { k: "tebalHalaman", v: 440 }, { k: "beratGram", v: 350 } ] },
{ _id: 2, nama: "Puzzle Peta Indonesia", atribut: [ { k: "usiaMinimum", v: 7 }, { k: "jumlahBidak", v: 500 } ] }
])
db.produk.createIndex({ "atribut.k": 1, "atribut.v": 1 })
db.produk.find({ atribut: { $elemMatch: { k: "tebalHalaman", v: 440 } } }, { nama: 1 })Output yang Dihasilkan:
switched to db latihan_modeling
{ ok: 1, dropped: 'latihan_modeling' }
{ acknowledged: true, insertedIds: { '0': 1, '1': 2 } }
atribut.k_1_atribut.v_1
[ { _id: 1, nama: 'Buku Bumi' } ]Satu compound index pada "atribut.k" dan "atribut.v" sekarang melayani query atribut mana pun — tebalHalaman, usiaMinimum, atau atribut yang baru dicetuskan bulan depan — tanpa menambah index baru. Inilah pola yang dipakai luas untuk katalog produk dengan atribut tak terbatas.
Extended Reference Pattern #
Chapter Duplikasi Data sudah memperlihatkan intinya; di sini kita tempatkan pada konteks relasi. Pesanan butuh nama dan kota pembeli di setiap halaman riwayat, tetapi tidak butuh seluruh profil. Extended Reference menyalin hanya field yang sering dibaca itu:
db.pengguna.insertOne({ _id: 1, nama: "Budi", kota: "Bandung", telepon: "0812-3456-7890", poinLoyalitas: 1240 })
db.pesanan.insertOne({
_id: 501, penggunaId: 1,
namaPembeli: "Budi", kotaPembeli: "Bandung",
total: 187000, tanggal: ISODate("2026-12-06T09:30:00Z")
})
db.pesanan.findOne({ _id: 501 })Output yang Dihasilkan:
{ acknowledged: true, insertedId: 1 }
{ acknowledged: true, insertedId: 501 }
{
_id: 501,
penggunaId: 1,
namaPembeli: 'Budi',
kotaPembeli: 'Bandung',
total: 187000,
tanggal: ISODate('2026-12-06T09:30:00.000Z')
}Dua field — namaPembeli dan kotaPembeli — cukup untuk merender riwayat pesanan tanpa $lookup; telepon dan poinLoyalitas tidak ikut disalin karena jarang dibaca di konteks pesanan. Kuncinya disiplin memilih: salin yang kecil dan sering dibaca, rujuk sisanya lewat penggunaId.
Schema Versioning Pattern #
Skema berubah: syarat hidup aplikasi. penulis semula string polos, kini perlu objek dengan nama dan kota. Daripada memigrasi sekaligus seluruh collection (menghentikan layanan), tiap document diberi schemaVersion dan migrasi berjalan bertahap:
db.buku.insertMany([
{ _id: 101, judul: "Bumi", penulis: "Tere Liye", schemaVersion: 1 },
{ _id: 102, judul: "Laut Bercerita", penulis: "Leila S. Chudori", schemaVersion: 1 }
])
db.buku.updateMany(
{ schemaVersion: 1 },
[ { $set: { penulis: { nama: "$penulis", kota: "tidak diketahui" }, schemaVersion: 2 } } ]
)
db.buku.find({}, { judul: 1, penulis: 1, schemaVersion: 1 })Output yang Dihasilkan:
{ acknowledged: true, insertedIds: { '0': 101, '1': 102 } }
{
acknowledged: true,
insertedId: null,
matchedCount: 2,
modifiedCount: 2,
upsertedCount: 0
}
[
{
_id: 101,
judul: 'Bumi',
penulis: { nama: 'Tere Liye', kota: 'tidak diketahui' },
schemaVersion: 2
},
{
_id: 102,
judul: 'Laut Bercerita',
penulis: { nama: 'Leila S. Chudori', kota: 'tidak diketahui' },
schemaVersion: 2
}
]Bedah migrasinya:
- Filter
{ schemaVersion: 1 }— hanya menyentuh document versi lama; document baru yang sudah lahir di versi 2 tidak tersentuh. - Update berbentuk aggregation pipeline —
$set: { penulis: { nama: "$penulis" } }membaca nilai lama$penulisdan membungkusnya menjadi subdocument; migrasi data nyata terjadi di server, satu perintah untuk semua document. - Aplikasi membaca dua versi — selama masa transisi, kode membaca
schemaVersionlalu menyesuaikan cara mengaksespenulis; begitu semua document bermigrasi, cabang kode versi lama dihapus.
Approximate Quantification Pattern #
Satu pola lagi yang ringkas: counter yang tidak harus exact. Menambah jumlahDilihat: +1 setiap halaman produk dibuka menulis jutaan update per hari untuk data yang tidak pernah ditampilkan satu-per-satu. Pola ini memperbarui counter hanya pada sebagian event — misalnya setiap pembelian ke-10 — menukar presisi dengan throughput: nilainya kira-kira, dan untuk “produk dilihat 12 ribu kali” kira-kira sudah cukup. Untuk angka yang harus exact seperti stok dan saldo, pola ini justru terlarang.
Rangkuman #
- Sembilan pola resmi — Attribute, Bucket, Computed, Extended Reference, Outlier, Polymorphic, Schema Versioning, Subset, Approximate — adalah kosakata bersama untuk solusi desain yang berulang.
- Attribute Pattern: pecah field beragam menjadi pasangan
k–v, satu index melayani semua. - Extended Reference Pattern: salin hanya field kecil yang sering dibaca dari document rujukan.
- Schema Versioning Pattern:
schemaVersionper document memungkinkan migrasi bertahap dengan pipeline update. - Approximate Quantification Pattern: counter kira-kira untuk statistik berfrekuensi tinggi yang tak harus exact.
Lima chapter berikutnya membahas pola-pola tersisa satu per satu, dimulai dari pola yang paling sering dipakai aplikasi modern: Polymorphic.