Data nyata jarang berbentuk datar: pelanggan punya alamat, alamat punya koordinat, pesanan punya metode pengiriman. Alih-alih memecahnya ke banyak tabel seperti di dunia relasional, MongoDB membiarkan kita menyematkan document di dalam document — nested document atau embedded document. Pola ini adalah alat paling penting dalam perancangan model data MongoDB, dan fondasinya justru sederhana: kurung kurawal di dalam kurung kurawal.
Peta materi Chapter ini:
- Menyematkan document beberapa level ke dalam document utama.
- Mengakses dan mencari nilai bersarang dengan dot notation.
- Pola embed beserta pertimbangan pertumbuhan datanya.
- Batas kedalaman bersarang yang didukung MongoDB.
Menyematkan Document di Dalam Document #
Kita mulai dengan satu document pelanggan yang menyematkan alamat lengkap — termasuk koordinat yang bersarang dua level:
use latihan_nested
db.pelanggan.insertOne({
nama: "Dewi Lestari",
email: "[email protected]",
alamat: {
jalan: "Jl. Merdeka No. 10",
kota: "Bandung",
kodePos: "40115",
koordinat: { lat: -6.9175, lng: 107.6191 }
}
})Output yang Dihasilkan:
switched to db latihan_nested
{
acknowledged: true,
insertedId: ObjectId('6ad380734ff5b88c5cd1c4a1')
}Struktur pohon yang terbentuk tampak seperti berikut:
Field alamat bernilai document utuh, dan di dalamnya field koordinat bernilai document lagi — total tiga level dari document utama. Semua tetap satu document BSON tunggal: dibaca, ditulis, dan diindeks sebagai satu kesatuan.
Mengakses dan Mencari dengan Dot Notation #
Akses di sisi JavaScript mengikuti aturan Chapter Struktur Document — dot notation berantai:
const d = db.pelanggan.findOne()
d.alamat
d.alamat.kota
d.alamat.koordinat.latOutput yang Dihasilkan:
{
jalan: 'Jl. Merdeka No. 10',
kota: 'Bandung',
kodePos: '40115',
koordinat: { lat: -6.9175, lng: 107.6191 }
}
Bandung
-6.9175d.alamat mengembalikan seluruh embedded document, d.alamat.kota menyelam satu level, dan d.alamat.koordinat.lat menembus dua level sekaligus. Yang membuat nested document benar-benar berguna adalah dot notation di sisi query. Jalur ke field bersarang ditulis sebagai satu string dengan titik sebagai pemisah level:
db.pelanggan.find({ "alamat.kota": "Bandung" })
db.pelanggan.find({ "alamat.kota": "Jakarta" })Output yang Dihasilkan:
[
{
_id: ObjectId('6ad380734ff5b88c5cd1c4a1'),
nama: 'Dewi Lestari',
email: '[email protected]',
alamat: {
jalan: 'Jl. Merdeka No. 10',
kota: 'Bandung',
kodePos: '40115',
koordinat: { lat: -6.9175, lng: 107.6191 }
}
}
]Query pertama mengembalikan document Dewi karena nilai alamat.kota cocok dengan "Bandung"; query kedua tidak mencetak apa-apa karena tidak ada pelanggan berkota Jakarta. Jalur bisa menembus berapa pun level:
db.pelanggan.find({ "alamat.koordinat.lat": -6.9175 })Output yang Dihasilkan:
[
{
_id: ObjectId('6ad380734ff5b88c5cd1c4a1'),
nama: 'Dewi Lestari',
email: '[email protected]',
alamat: {
jalan: 'Jl. Merdeka No. 10',
kota: 'Bandung',
kodePos: '40115',
koordinat: { lat: -6.9175, lng: 107.6191 }
}
}
]Query tersebut menembus dua level embedded document (alamat → koordinat) dan tetap menemukan document Dewi. Perhatikan bahwa seluruh jalur ditulis dalam satu string terkurung tanda kutip — "alamat.koordinat.lat" — bukan tiga field terpisah.
Pola Embed dan Batasnya #
Kapan menyematkan dan kapan memisahkan? Prinsip dasarnya: sematkan data yang selalu dibaca bersama induknya dan ukurannya terbatas — alamat pelanggan, profil singkat penulis artikel, item pesanan pada struk jadi. Data yang tumbuh tanpa batas (komentar artikel, riwayat transaksi bertahun-tahun) pada akhirnya lebih cocok menjadi collection tersendiri yang merujuk induknya lewat ObjectId; pembahasan lengkapnya menanti Section Data Modeling.
Kedalaman bersarang sendiri punya batas. Dokumentasi MongoDB menyebut dukungan hingga 100 level bersarang untuk satu document — jauh melebihi kebutuhan model data yang sehat, yang biasanya berhenti di dua sampai empat level. Server tetap menolak kedalaman yang ekstrem, dan kita bisa menyaksikannya dengan membangun document sangat dalam memakai perulangan:
try {
let doc = { nilai: "terdalam" }
for (let i = 0; i < 200; i++) { doc = { level: doc } }
db.sangat_dalam.insertOne(doc)
print("berhasil disimpan")
} catch (e) {
print(e.codeName)
}Output yang Dihasilkan:
OverflowPerulangan di atas membungkus document inti 200 kali sehingga terbentuk 201 level kedalaman. Insert ditolak server dengan galat Overflow — parser BSON menolak memindai document yang terlalu dalam. Angka pasti dari mana penolakan dimulai bukan sesuatu yang kita andalkan; yang penting dipahami adalah kedalaman didukung hingga 100 level, dan model data yang baik jauh di bawahnya.
Sebagai penutup, bersihkan database latihan:
db.dropDatabase()Output yang Dihasilkan:
{ ok: 1, dropped: 'latihan_nested' }Rangkuman #
- Nested document adalah document di dalam field document lain; seluruh pohon tetap satu document BSON.
- Akses di JavaScript:
d.alamat.koordinat.lat; pencarian di query:{ "alamat.koordinat.lat": -6.9175 }— jalur dalam satu string berkutip. - Sematkan data yang selalu dibaca bersama induk dan terbatas ukurannya; data yang tumbuh tanpa batas lebih baik jadi collection tersendiri.
- Kedalaman bersarang didukung hingga 100 level; ekstrem di luar itu ditolak galat
Overflowseperti yang kita buktikan.
Satu bentuk bersarang masih tersisa dan justru paling sering dipakai: array. Chapter berikutnya menutup Section ini dengan bahasan lengkap tentangnya.