Merangkai seluruh materi series dalam studi kasus e-commerce: merancang schema users, product catalog, orders, dan analytics; membangun deployment dengan replica set, TLS, backup, dan monitoring; serta meninjau checklist kesiapan produksi sebagai penutup seri.

Selamat — kalian telah menempuh 19 episode, dari setup, CRUD, query lanjutan, schema design, aggregation, indexing, transaction, replica set, sharding, security, backup, hingga monitoring. Kini tiba saatnya bukti akhir: merangkai semuanya menjadi satu arsitektur production-grade. Episode 20 adalah studi kasus e-commerce yang menyatukan seluruh pengetahuan: merancang schema users & auth, product catalog, orders & inventory, dan analytics, lalu deployment architecture dengan replica set, TLS, backup, dan monitoring, ditutup checklist kesiapan produksi dan refleksi akhir.
User memegang profil dan daftar alamat. Karena jumlah alamat per user kecil dan selalu dibaca bersama profil, kita embed alamat sebagai array (pola one-to-few dari episode 7):
{
"_id": ObjectId("66aaaaaaaaaaaaaaaaaaaaaaaa"),
"email": "siti@example.com",
"name": "Siti Rahma",
"role": "customer",
"status": "active",
"nationalIdEncrypted": BinData(0, "...ciphertext..."),
"addresses": [
{ "label": "rumah", "street": "Jl. Merdeka No. 10", "city": "Jakarta", "zip": "10110" }
],
"createdAt": ISODate("2026-01-15T09:00:00Z")
}Perhatikan nationalIdEncrypted — NIK disimpan sebagai ciphertext hasil CSFLE (episode 17): dienkripsi di sisi aplikasi, sehingga server pun tidak bisa membacanya.
email — menjamin tidak ada duplikat akun di level database.{ email: 1 } pada dokumen status: "active" — user yang di-soft-delete tidak mengunci emailnya.db.users.createIndex({ email: 1 }, { unique: true })
db.users.createIndex({ email: 1 }, { unique: true, partialFilterExpression: { status: "active" } })Produk punya atribut yang sangat beragam: fashion punya size dan color, elektronik punya specs. Ini pekerjaan sempurna untuk flexible schema — atribut dinamis disimpan sebagai embedded document (episode 7), sehingga tiap kategori bebas menentukan strukturnya:
{
"_id": ObjectId("66bbbbbbbbbbbbbbbbbbbbbbbb"),
"name": "Laptop Gaming 15",
"category": "elektronik",
"price": NumberDecimal("15000000"),
"stock": 5,
"tags": ["best-seller", "baru"],
"specs": { "ram": "16GB", "storage": "512GB SSD" }
}db.products.createIndex({ category: 1, price: 1 })
db.products.createIndex({ name: "text", description: "text" })
db.flashSales.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 }){ category: 1, price: 1 } — mengikuti aturan ESR (episode 12) untuk query "produk elektronik dengan harga tertentu" yang paling sering dijalankan.flashSales — dokumen promo lelang otomatis dihapus setelah satu jam, tanpa cron job manual.Membuat order sambil mengurangi stok harus atomik — jika stok terpotong tapi order gagal, atau sebaliknya, toko kalian kacau. Solusinya: multi-document ACID transaction (episode 14):
const session = client.startSession();
session.startTransaction();
try {
await products.updateOne({ _id: productId, stock: { $gte: qty } }, { $inc: { stock: -qty } }, { session });
await orders.insertOne(
{ userId, items: [{ productId, qty, priceAtPurchase }], total, status: "pending", createdAt: new Date() },
{ session }
);
await session.commitTransaction();
} catch (err) {
await session.abortTransaction();
} finally {
await session.endSession();
}Dua detail cerdas: filter stock: { $gte: qty } memastikan pengurangan stok hanya terjadi jika persediaan mencukupi (jika tidak, transaksi di-abort), dan priceAtPurchase adalah snapshot harga (episode 7) — order tetap mencatat harga saat pembelian meski harga berubah nanti.
Setelah order dibuat, statusnya berubah-ubah: pending, paid, shipped, delivered. Untuk memberi tahu user secara real-time, kita pasang change stream (episode 18) pada collection orders:
const changeStream = orders.watch([
{ $match: { operationType: "update", "updateDescription.updatedFields.status": { $exists: true } } }
]);
changeStream.on("change", (event) => {
notifyUser(event.documentKey._id, event.updateDescription.updatedFields.status);
});Setiap status order berubah, aplikasi mengirim notifikasi ke user — tanpa polling, hampir tanpa latensi. Ini juga sumber data untuk pipeline sinkronisasi ke search engine atau data warehouse.
Dengan aggregation pipeline (episode 9 dan 10), kebutuhan analitik dipenuhi dalam query terpusat. Laporan penjualan harian per kategori:
db.orders.aggregate([
{ $match: { status: "paid" } },
{ $unwind: "$items" },
{ $addFields: { day: { $dateToString: { format: "%Y-%m-%d", date: "$createdAt" } } } },
{ $group: { _id: { day: "$day", category: "$items.category" }, revenue: { $sum: { $multiply: ["$items.priceAtPurchase", "$items.qty"] } } } },
{ $sort: { "_id.day": 1 } }
])Halaman dashboard butuh beberapa ringkasan sekaligus — total revenue, produk terlaris, dan order terbaru. $facet menjalankannya dalam satu query yang konsisten:
db.orders.aggregate([
{ $match: { status: "paid" } },
{ $facet: {
"summary": [{ $group: { _id: null, totalRevenue: { $sum: "$total" } } }],
"topProducts": [{ $unwind: "$items" }, { $group: { _id: "$items.productId", qty: { $sum: "$items.qty" } } }, { $sort: { qty: -1 } }, { $limit: 10 }],
"recent": [{ $sort: { createdAt: -1 } }, { $limit: 5 }]
} }
])3-Member Replica Set (rs0): Primary tulis + baca, Secondary baca untuk laporan + kandidat failover
Lapisan keamanan: SCRAM-SHA-256 untuk semua user, RBAC role per service, TLS semua koneksi, CSFLE field sensitif
Otomasi operasional: mongodump tiap 6 jam + uji restore bulanan, Prometheus/Grafana + alerting, profiler slowms 100authorization: enabled) dan tidak ada user default.root.explain() untuk memverifikasi IXSCAN pada query utama.Selamat — kalian telah menempuh seluruh perjalanan Belajar MongoDB dari nol hingga production-grade. Di episode penutup ini kalian merangkai semuanya: schema users dengan embedded addresses dan CSFLE, product catalog dengan flexible attributes dan compound plus TTL index, order & inventory dengan ACID transaction dan change streams, serta analytics dengan aggregation pipeline dan $facet. Kalian juga menyusun deployment replica set tiga anggota dengan TLS, backup otomatis, dan monitoring Prometheus/Grafana, plus checklist kesiapan produksi yang siap pakai.
Inti yang harus dibawa pulang:
Terima kasih sudah bertahan sampai akhir. Kalian bukan lagi sekadar "tahu MongoDB" — kalian punya kerangka berpikir yang utuh: dari cara menulis query, merancang schema, mengamankan, memantau, hingga membangun sistem produksi. Sekarang saatnya membawa pengetahuan ini ke proyek kalian sendiri. Mulailah kecil, verifikasi dengan explain(), dan jadikan setiap keputusan didasari data — persis seperti yang kalian pelajari di seluruh seri ini. Selamat berkarya!