Menulis data pertama ke MongoDB menggunakan insertOne, insertMany, dan bulkWrite untuk batch operation campuran, lalu membaca kembali data tersebut dengan find, findOne, serta projection untuk memilih field yang dikembalikan.

Setelah memahami struktur data di episode 2, sekarang waktunya praktik. Episode 3 membuka fase CRUD — Create, Read, Update, Delete — yang akan menemani kalian sepanjang karier sebagai developer MongoDB. Episodes kali ini fokus pada dua operasi pertama: Create (menyimpan data) dan Read (mengambil data).
Kedua operasi ini adalah operasi paling sering dipakai di dunia nyata. Setiap endpoint API yang menerima request POST memakai insert di belakangnya, dan hampir semua endpoint GET memakai find. Roadmap episode 3: pertama kita pelajari tiga cara menyimpan data — insertOne, insertMany, dan bulkWrite; kedua kita pelajari cara mengambil data — find, findOne; dan ketiga kita kuasai projection untuk mengontrol bentuk hasil query. Mari mulai.
Fungsi insertOne menyisipkan satu dokumen ke dalam collection. Jika collection belum ada, MongoDB membuatnya otomatis. Perhatikan cara memanggilnya:
db.users.insertOne({
name: "Siti Rahma",
email: "siti@example.com",
age: 24,
role: "student"
})Fungsi ini mengembalikan hasil berisi acknowledged: true dan insertedId — nilai _id yang diberikan ke dokumen baru:
{
"acknowledged": true,
"insertedId": ObjectId("66xxxxxxxxxxxxxxxxxxxxxxxx")
}insertedId inilah kunci yang akan kalian pakai untuk merujuk dokumen ini di operasi berikutnya.
Saat punya banyak data yang harus disimpan sekaligus, jangan panggil insertOne berulang-ulang. Gunakan insertMany yang mengirim semua dokumen dalam satu round-trip ke server — jauh lebih cepat:
db.products.insertMany([
{ name: "Mouse Wireless", price: 150000, category: "elektronik" },
{ name: "Keyboard Mechanical", price: 750000, category: "elektronik" },
{ name: "Kaos Polos", price: 99000, category: "fashion" }
])Hasilnya berisi array insertedIds untuk setiap dokumen. Catatan penting: insertMany adalah operasi default ordered — jika satu dokumen gagal di tengah, sisanya tidak diproses. Jika kalian ingin yang berhasil tetap disimpan, tambahkan opsi { ordered: false }.
bulkWrite adalah fitur paling fleksibel: satu panggilan bisa memuat campuran operasi insert, update, dan delete sekaligus. Ini sangat berguna untuk proses sinkronisasi data di mana kalian harus menambah, memperbarui, dan menghapus dalam satu batch:
db.products.bulkWrite([
{ insertOne: { document: { name: "Headset", price: 300000, category: "elektronik" } } },
{ updateOne: { filter: { name: "Kaos Polos" }, update: { $set: { price: 89000 } } } },
{ deleteOne: { filter: { name: "Mouse Wireless" } } }
])Hasilnya memberi ringkasan berapa insert, update, dan delete yang dieksekusi. bulkWrite mengirim semua operasi dalam jumlah round-trip minimal — investasi yang terbayar saat volume data besar.
Fungsi find adalah cara utama membaca data. Ia menerima filter (kriteria pencocokan) dan mengembalikan cursor yang bisa diiterasi:
db.products.find({})find({}) dengan filter kosong mengembalikan seluruh dokumen. Dengan filter, kalian membatasi hasil berdasarkan kriteria:
db.products.find({ category: "elektronik" })Kedua perintah di atas mengembalikan semua dokumen yang cocok — hasilnya adalah cursor, bukan array. Untuk melihat hasilnya di mongosh, cursor tersebut otomatis di-iterate; di aplikasi, kalian perlu memanggil .toArray() atau mengiterasi cursor.
findOne mengembalikan dokumen pertama yang cocok dengan filter, atau null jika tidak ada. Ini pasangan ideal untuk operasi yang butuh satu record:
db.users.findOne({ email: "siti@example.com" })Perbedaan kunci: find mengembalikan cursor (bisa kosong tanpa error), sementara findOne langsung mengembalikan dokumen atau null. Untuk kasus "cek apakah user ini ada" atau "ambil profil user ini", findOne jauh lebih praktis.
Saat dokumen semakin besar (bisa puluhan field), mengembalikan semuanya setiap kali query adalah pemborosan bandwidth dan memory. Projection adalah parameter kedua di find yang menentukan field mana yang dikembalikan:
db.users.find({ role: "student" }, { name: 1, email: 1 })Nilai 1 artinya sertakan field tersebut, 0 artinya kecualikan. Untuk mengecualikan _id (yang selalu disertakan secara default), set _id: 0:
db.users.find({}, { name: 1, email: 1, _id: 0 })Info
Aturan projection: kalian bisa mencampur 1 dan 0 dalam satu projection selama yang bernilai 0 hanya _id. Misalnya { name: 1, email: 1, _id: 0 } valid, tapi { name: 1, address: 0 } tidak valid — MongoDB menolak campuran inclusion dan exclusion selain _id. Pilih satu gaya: include semua yang dibutuhkan, atau exclude yang tidak dibutuhkan.
Mari rangkai semua yang dipelajari dalam skenario nyata: toko online kecil. Pertama kita simpan beberapa produk, lalu kita baca dengan berbagai cara:
db.products.insertMany([
{ name: "Laptop Gaming", price: 15000000, category: "elektronik", stock: 5 },
{ name: "Meja Kantor", price: 1200000, category: "furniture", stock: 10 },
{ name: "Sneaker", price: 450000, category: "fashion", stock: 25 }
])
db.products.findOne({ name: "Sneaker" })
db.products.find({ stock: { $gt: 8 } }, { name: 1, price: 1, _id: 0 })Perhatikan operator $gt di query terakhir — itu adalah operator perbandingan yang akan kita bedah secara mendalam di episode 5. Untuk sekarang, cukup pahami bahwa { stock: { $gt: 8 } } berarti "stock lebih besar dari 8".
Warning
Hati-hati dengan find({}) pada collection besar tanpa filter. Tanpa index yang tepat, MongoDB harus memindai seluruh collection untuk mengembalikan hasil — ini disebut COLLSCAN, musuh utama performa. Kita akan membahas index dan optimasi query di episode 12 dan 13. Untuk episode ini, cukup biasakan selalu menyertakan filter yang selektif.
Pada episode 3 ini kalian telah menguasai dua pilar pertama CRUD. Untuk Create: insertOne untuk satu dokumen, insertMany untuk banyak dokumen dalam satu round-trip, dan bulkWrite untuk batch operasi campuran insert-update-delete. Untuk Read: find yang mengembalikan cursor dengan filter, findOne untuk satu dokumen pertama yang cocok, dan projection untuk memilih field yang dikembalikan serta mengecualikan _id.
Inti yang harus dibawa pulang:
insertMany jauh lebih cepat daripada loop insertOne — selalu gunakan untuk data massal.bulkWrite mengkombinasikan insert, update, dan delete dalam satu panggilan.find mengembalikan cursor; findOne mengembalikan dokumen atau null.1 (include) dan 0 (exclude); hanya _id yang bisa dikecualikan saat mode include.Di episode 4 berikutnya kita menuntaskan sisa operasi CRUD: Update & Delete Operations. Kalian akan memperbarui dokumen dengan updateOne, updateMany, dan replaceOne, mengenal update operators seperti $set, $inc, dan $push, menghapus data dengan deleteOne dan deleteMany, serta memanfaatkan pola upsert yang cerdas. Sampai jumpa di episode 4!