Untuk membuat hubungan di MongoDB, sematkan dokumen BSON di dalam dokumen lain, atau rujuk dari yang lain.
Basis data MongoDB bekerja secara berbeda dengan basis data relasional. Ini juga berlaku untuk hubungan.
Di MongoDB, Anda dapat membuat hubungan menggunakan salah satu dari dua metode berikut:
- Dokumen tersemat.
- Dokumen yang dirujuk.
Metode yang Anda gunakan akan bergantung pada data, dan cara Anda ingin mengkueri data tersebut.
Hubungan Tertanam
Dengan MongoDB, Anda dapat menyematkan dokumen di dalam dokumen. Oleh karena itu, satu dokumen dapat berisi hubungannya sendiri.
Sebenarnya, kita sudah membuat hubungan menggunakan metode ini saat pertama kali membuat dokumen.
Hubungan Satu-ke-Satu
Hubungan satu-ke-satu adalah di mana dokumen induk memiliki satu anak, dan anak tersebut memiliki satu orang tua.
Misalnya, aturan bisnis mungkin mengatakan bahwa seorang artis hanya dapat memiliki satu alamat dan alamat tersebut hanya dapat dimiliki oleh satu artis.
Kode berikut membuat hubungan satu-ke-satu, yang disematkan di dalam dokumen.
db.artists.insert( { _id : 2, artistname : "Prince", address : { street : "Audubon Road", city : "Chanhassen", state : "Minnesota", country : "United States" } } )
Hasil:
WriteResult({ "nInserted" : 1 })
Hubungan Satu-ke-Banyak
satu-ke-banyak hubungan adalah di mana dokumen induk dapat memiliki banyak dokumen anak, tetapi dokumen anak hanya dapat memiliki satu dokumen induk.
Jadi, aturan bisnis lain mungkin mengatakan bahwa satu artis dapat memiliki banyak album, tetapi satu album hanya dapat dimiliki oleh satu artis.
Menjalankan kode berikut akan membuat hubungan satu-ke-banyak:
db.artists.insert( { _id : 3, artistname : "Moby", albums : [ { album : "Play", year : 1999, genre : "Electronica" }, { album : "Long Ambients 1: Calm. Sleep.", year : 2016, genre : "Ambient" } ] } )
Hasil:
WriteResult({ "nInserted" : 1 })
Hubungan Referensi Dokumen
Anda dapat menggunakan referensi dokumen untuk membuat hubungan. Daripada menyematkan dokumen anak ke dalam dokumen induk (seperti yang kami lakukan di atas), Anda memisahkan dokumen anak ke dalam dokumen yang berdiri sendiri.
Jadi kita bisa melakukan ini:
Dokumen Induk
db.artists.insert( { _id : 4, artistname : "Rush" } )
Dokumen Anak
Kami akan memasukkan 3 dokumen anak — satu untuk setiap anggota band:
db.musicians.insert( { _id : 9, name : "Geddy Lee", instrument : [ "Bass", "Vocals", "Keyboards" ], artist_id : 4 } )
db.musicians.insert( { _id : 10, name : "Alex Lifeson", instrument : [ "Guitar", "Backing Vocals" ], artist_id : 4 } )
db.musicians.insert( { _id : 11, name : "Neil Peart", instrument : "Drums", artist_id : 4 } )
Mengajukan Kueri Hubungan
Setelah memasukkan dua dokumen di atas, Anda dapat menggunakan $lookup
untuk melakukan gabungan luar kiri pada dua koleksi.
Ini, dalam hubungannya dengan aggregate()
metode, dan $match
untuk menentukan artis tertentu yang Anda minati, akan mengembalikan dokumen orang tua dan anak dalam satu dokumen.
db.artists.aggregate([ { $lookup: { from: "musicians", localField: "_id", foreignField: "artist_id", as: "band_members" } }, { $match : { artistname : "Rush" } } ]).pretty()
Hasil:
{ "_id" : 4, "artistname" : "Rush", "band_members" : [ { "_id" : 9, "name" : "Geddy Lee", "instrument" : [ "Bass", "Vocals", "Keyboards" ], "artist_id" : 4 }, { "_id" : 10, "name" : "Alex Lifeson", "instrument" : [ "Guitar", "Backing Vocals" ], "artist_id" : 4 }, { "_id" : 11, "name" : "Neil Peart", "instrument" : "Drums", "artist_id" : 4 } ] }
Anda dapat melihat bahwa dua kolom pertama berasal dari koleksi artis, dan sisanya dari koleksi musisi.
Jadi jika Anda hanya menanyakan koleksi artis itu sendiri:
db.artists.find( { artistname : "Rush" } )
Anda hanya akan mendapatkan ini:
{ "_id" : 4, "artistname" : "Rush" }
Tidak ada data terkait yang dikembalikan.
Kapan menggunakan Dokumen Tersemat vs Dokumen Referensi
Kedua metode menciptakan hubungan memiliki pro dan kontra. Ada kalanya Anda mungkin menggunakan dokumen yang disematkan, dan di lain waktu Anda akan menggunakan dokumen yang direferensikan.
Kapan menggunakan Hubungan Tertanam
Salah satu manfaat utama menggunakan metode hubungan tertanam adalah kinerja. Saat hubungan disematkan di dalam dokumen, kueri akan berjalan lebih cepat daripada jika tersebar di beberapa dokumen. MongoDB hanya perlu mengembalikan satu dokumen, daripada menggabungkan beberapa dokumen untuk mengambil hubungan. Ini dapat memberikan peningkatan kinerja yang besar — terutama saat bekerja dengan banyak data.
Hubungan yang disematkan juga membuat kueri lebih mudah ditulis. Daripada menulis kueri kompleks yang menggabungkan banyak dokumen melalui pengenal uniknya, Anda dapat mengembalikan semua data terkait dalam satu kueri.
Pertimbangan lain yang perlu diingat adalah bahwa, MongoDB hanya dapat memastikan atomisitas pada tingkat dokumen. Pembaruan dokumen untuk satu dokumen selalu bersifat atomik, tetapi tidak untuk beberapa dokumen.
Saat beberapa pengguna mengakses data, selalu ada kemungkinan dua atau lebih pengguna akan mencoba memperbarui dokumen yang sama dengan data yang berbeda. Dalam hal ini, MongoDB akan memastikan bahwa tidak ada konflik yang terjadi dan hanya satu kumpulan data yang diperbarui dalam satu waktu. MongoDB tidak dapat memastikan ini di banyak dokumen.
Jadi secara umum, hubungan tertanam dapat digunakan dalam banyak kasus, selama dokumen tetap dalam batas ukuran (16 megabyte pada saat penulisan), dan/atau batas bersarangnya (kedalaman 100 level pada saat penulisan).
Namun, hubungan yang disematkan tidak sesuai untuk semua kesempatan. Mungkin ada situasi di mana lebih masuk akal untuk membuat hubungan referensi dokumen.
Kapan menggunakan Hubungan Referensi
Untuk data yang perlu diulang di banyak dokumen, akan sangat membantu jika mereka memilikinya di dokumen terpisah mereka sendiri. Hal ini dapat mengurangi kesalahan dan membantu menjaga data tetap konsisten (sambil mengingat bahwa pembaruan banyak dokumen tidak bersifat atomik).
Menggunakan contoh di atas, satu musisi bisa menjadi anggota (atau mantan anggota) dari banyak band. Beberapa mungkin juga memproduksi album untuk artis lain, mengajar siswa, menjalankan klinik, dll. Selain itu, banyak data dapat disimpan untuk setiap musisi. Jadi memiliki dokumen terpisah untuk setiap musisi masuk akal dalam kasus ini.
Selain itu, jika menurut Anda dokumen yang disematkan mungkin melebihi batas ukuran file yang ditetapkan oleh MongoDB, maka Anda harus menyimpan beberapa data dalam dokumen terpisah.