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 #

PolaIntiKapan dipakaiBab detail
AttributeField langka/beragam dipecah menjadi pasangan k–v dalam arrayField bervariasi antar document, query perlu satu index lintas atributBab ini
BucketData deret waktu dikelompokkan per rentang (menit/jam)Sensor, log, metrik berfrekuensi tinggiBucket Pattern
ComputedHasil perhitungan disimpan di documentAgregasi mahal yang dibaca berulang (rata-rata, total)Computed Pattern
Extended ReferenceSebagian field yang sering dibaca disalin dari document rujukanDuplikasi kecil demi menghindari $lookup di jalur panasBab ini
OutlierEntitas ekstrem dipisah representasinya1% data dengan skala ratusan kali dari populasi umumOutlier Pattern
PolymorphicBanyak bentuk document dalam satu collection dengan field pembedaEntitas sejenis dengan variasi fieldPolymorphic Pattern
Schema VersioningField schemaVersion menandai bentuk documentMigrasi bertahap tanpa henti layananBab ini
SubsetHanya subset data panas yang embed di indukArray besar yang hanya ujungnya yang dibacaSubset Pattern
Approximate QuantificationCounter diperbarui sebagian, nilainya kira-kiraStatistik 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:

js
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:

text
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:

js
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:

text
{ 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:

js
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:

text
{ 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:

  1. Filter { schemaVersion: 1 } — hanya menyentuh document versi lama; document baru yang sudah lahir di versi 2 tidak tersentuh.
  2. Update berbentuk aggregation pipeline — $set: { penulis: { nama: "$penulis" } } membaca nilai lama $penulis dan membungkusnya menjadi subdocument; migrasi data nyata terjadi di server, satu perintah untuk semua document.
  3. Aplikasi membaca dua versi — selama masa transisi, kode membaca schemaVersion lalu menyesuaikan cara mengakses penulis; 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: schemaVersion per 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.