Karena mongosh berdiri di atas Node.js, setiap hasil perintah bisa kita simpan ke variabel JavaScript lalu dipakai ulang — kemampuan yang mengubah shell dari mesin ketik-perintah menjadi tempat eksperimen sungguhan. Tanpa variabel, hasil findOne() hilang begitu layar bergulir; dengan variabel, hasil itu bisa diolah, dihitung, dan digabung dengan hasil lain. Chapter ini membahas const/let, penyimpanan hasil query, cursor sebagai objek, fungsi kecil, dan perbedaan console.log() dengan hasil ekspresi.

const dan let #

Deklarasi variabel mengikuti JavaScript modern: const untuk nilai yang tidak akan ditugaskan ulang, let untuk yang akan berubah. Sebagai bahan latihan, siapkan dulu database berisi empat produk:

js
use latihan_shell
js
db.produk.insertMany([
  { nama: "Pensil", harga: 3000 },
  { nama: "Buku", harga: 12000 },
  { nama: "Penghapus", harga: 2500 },
  { nama: "Spidol", harga: 8000 }
])

Output yang Dihasilkan:

text
{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId('6ad37f2c7298e4b034a1c830'),
    '1': ObjectId('6ad37f2c7298e4b034a1c831'),
    '2': ObjectId('6ad37f2c7298e4b034a1c832'),
    '3': ObjectId('6ad37f2c7298e4b034a1c833')
  }
}

Sekarang deklarasi dua variabel dan hitung jumlah produk memakai salah satunya:

js
const namaToko = "Toko Siti"
let jumlahStok = 0
db.produk.find().forEach(() => jumlahStok++)
jumlahStok

Output yang Dihasilkan:

text
4

Perhatikan kebiasaan penting REPL: pernyataan penugasan tidak menghasilkan echo, dan dari empat baris di atas hanya baris terakhir (jumlahStok) yang hasilnya dicetak. Nilai 4 membuktikan forEach() menambah jumlahStok sebanyak empat kali — sekian banyak document yang dilewati cursor. Kata kunci var juga dikenali, tetapi gunakan const/let yang ruang lingkupnya lebih disiplin.

Menyimpan Hasil Query dalam Variabel #

Hasil findOne() adalah document yang sudah berbentuk objek JavaScript, sehingga bisa langsung disimpan dan field-nya diakses dengan notasi titik:

js
const buku = db.produk.findOne({ nama: "Buku" })
buku
buku.harga
typeof buku

Output yang Dihasilkan:

text
{
  _id: ObjectId('6ad37f2c7298e4b034a1c831'),
  nama: 'Buku',
  harga: 12000
}
12000
object

Empat baris keluaran di atas mewakili tiga ekspresi terakhir: document lengkap untuk buku, nilai field harga, dan jenis datanya. Sekali disimpan, buku.harga bisa dipakai berulang tanpa query ulang ke server — variabel menyimpan salinan hasil, bukan tautan langsung ke data di server.

Cursor adalah Objek #

Berbeda dengan findOne(), find() tidak mengembalikan document melainkan cursor — objek yang menampung aliran hasil dari server:

js
const kursor = db.produk.find()
typeof kursor

Output yang Dihasilkan:

text
object

Cursor baru mengirim dan menampilkan data saat diiterasi. Method forEach() milik cursor menerima satu fungsi yang dipanggil untuk setiap document:

js
kursor.forEach(produk => print(produk.nama))

Output yang Dihasilkan:

text
Pensil
Buku
Penghapus
Spidol

Setiap document ditampung sementara ke parameter produk, lalu print() mencetak field nama. Cursor sekali jalan: setelah seluruh hasil terkirim, cursor yang sama tidak bisa diiterasi ulang — jalankan find() kembali bila perlu memproses sekali lagi.

Fungsi Kecil dan Template Literal #

Rumus yang dipakai berulang layak dibungkus fungsi. Bentuk paling ringkas adalah arrow function:

js
const hargaSetelahDiskon = (harga, persen) => harga * (100 - persen) / 100
hargaSetelahDiskon(buku.harga, 20)

Output yang Dihasilkan:

text
9600

Fungsi hargaSetelahDiskon() menerima dua argumen dan mengembalikan hasil perhitungan; nilai 12000 dipotong 20% menjadi 9600. Untuk merangkai teks dan nilai, template literal dengan backtick lebih rapi daripada penggabungan string biasa:

js
`Diskon ${buku.nama}: Rp${buku.harga - hargaSetelahDiskon(buku.harga, 20)}`

Output yang Dihasilkan:

text
Diskon Buku: Rp2400

Ekspresi di dalam ${} dievaluasi lebih dulu lalu hasilnya disisipkan ke teks — di sini selisih harga sebelum dan sesudah diskon dihitung sekaligus ditampilkan.

console.log dan print vs Hasil Ekspresi #

Echo hasil hanya terjadi untuk statement terakhir; di dalam loop, callback, atau fungsi, satu-satunya cara menampilkan nilai adalah mencetaknya secara eksplisit. Bandingkan dua iterasi berikut:

js
db.produk.find().forEach(produk => produk.nama)

Blok di atas sunyi — produk.nama mengembalikan nilai, tetapi forEach() membuangnya dan REPL tidak meng-echo apa pun dari dalam callback. Tambahkan print() dan hasilnya langsung terlihat:

js
db.produk.find().forEach(produk => print(produk.nama))

Output yang Dihasilkan:

text
Pensil
Buku
Penghapus
Spidol

Fungsi console.log() bekerja dengan cara yang sama dan menerima beberapa argumen sekaligus:

js
console.log("Stok", namaToko, ":", jumlahStok, "produk")

Output yang Dihasilkan:

text
Stok Toko Siti : 4 produk

Sebelum menutup chapter, bersihkan database latihan:

js
db.dropDatabase()

Output yang Dihasilkan:

text
{ ok: 1, dropped: 'latihan_shell' }

Rangkuman #

  • const untuk nilai tetap, let untuk yang berubah; pernyataan penugasan tidak di-echo, hanya statement terakhir yang hasilnya dicetak.
  • findOne() mengembalikan document yang bisa disimpan lalu field-nya diakses (buku.harga); simpanan adalah salinan, bukan tautan langsung ke server.
  • find() mengembalikan cursor — objek yang data mengalir saat diiterasi, dan sekali jalan tidak bisa diulang.
  • Arrow function membungkus rumus berulang; template literal menyisipkan ekspresi ke teks lewat ${}.
  • Di dalam loop dan callback, gunakan print() atau console.log(); echo REPL tidak menjangkau sana.