Kotak pencarian adalah pintu masuk utama sebuah toko daring: pembaca mengetik “pensil untuk sketsa”, pembeli lain menyaring “buku di bawah seratus ribu”. Dua kebutuhan itu menuntut dua mesin berbeda — pencarian teks bebas dan filter terstruktur — yang harus bekerja dalam satu query. Proyek ini mengajak kita membangun fitur pencarian produk untuk katalog toko buku dan alat tulis: dari rancangan schema yang sadar pencarian, query $text dengan frasa dan negasi, text index berbobot, sampai pagination hasil dan pengukuran performa lewat explain().

Sama seperti proyek-proyek sebelumnya, seluruh kode berbentuk skrip mongosh yang dijalankan lewat --file — fokus kita tetap pada perancangan data dan bahasa query, bukan kerangka aplikasi.

Tujuan Proyek #

Setelah menyelesaikan proyek ini, kita memiliki katalog pencarian dengan kemampuan berikut:

  • Schema yang sadar pencarian: field teks bebas (nama, deskripsi) dipisahkan dari field filter (kategori, harga) dan field pencocokan tepat (tag).
  • Pencarian teks lengkap: kata tunggal, beberapa kata dengan logika OR, frasa eksak di dalam kutip ganda, sampai negasi dengan awalan - — semuanya terurut berdasarkan skor relevansi.
  • Filter gabungan: satu query memadukan $text dengan kategori dan rentang harga sekaligus.
  • Text index berbobot: kecocokan di nama diberi bobot 10 kali lipat dari deskripsi lewat opsi weights, dan batasan satu text index per collection dibuktikan langsung.
  • Pagination dua jalur: hasil teks dihalaman lewat sort skor + skip/limit, hasil filter lewat keyset pagination harga + _id.
  • Bukti performa: explain("executionStats") membandingkan docsExamined regex vs text index, dan filter dengan vs tanpa compound index.

Prasyarat #

Materi proyek ini bersumber dari tiga Section:

  • Indexing — chapter Text Index (pembuatan, $text, bahasa, weights) dan Compound Index (urutan field equality-range) yang menjadi fondasi Bagian 1 dan 3.
  • Search dan Geospatial — chapter Text Search untuk pola frasa dan negasi, serta Keterbatasan Text Index yang menjelaskan kenapa hanya satu text index per collection.
  • Aggregation dan Indexing lanjutan — $meta: "textScore" untuk skor, explain() untuk rencana query, dan pola keyset pagination dari chapter Index Ordering.

Lingkungan pengerjaan sama seperti proyek sebelumnya: single-node replica set rs0 di 127.0.0.1:27017, diakses mongosh dengan connection string mongodb://127.0.0.1:27017/?directConnection=true.

Hasil Akhir #

Proyek menghasilkan database proyek_pencarian berisi collection katalog dengan 60 produk, satu text index berbobot, dan satu compound index:

BerkasPeran
src/katalog-seed.jsMereset database; 60 produk buku dan alat tulis + text index awal
src/pencarian-teks.jsQuery kata, beberapa kata, frasa, negasi, dan skor
src/pencarian-filter.js$text dipadukan filter kategori dan rentang harga
src/buat-index.jsText index ulang dengan weights + compound index filter
src/uji-performa.jsPengukuran docsExamined regex vs text index, index vs COLLSCAN
tests/semua-tes.jsSuite tes mandiri; mencetak SEMUA TES LULUS

Peta Bagian #

Proyek dikerjakan dalam empat bagian berurutan — setiap bagian dibangun di atas kondisi data bagian sebelumnya:

  1. Bagian 1 — Product Schema: pola akses, pemilihan field text index, dan pengisian 60 produk.
  2. Bagian 2 — Text dan Filter Queries: empat bentuk $search dan filter gabungan terstruktur.
  3. Bagian 3 — Indexing: batasan satu text index, weights untuk nama, dan compound index filter.
  4. Bagian 4 — Pagination dan Performance: dua jalur pagination, pengukuran explain, dan suite tes penutup.

Menjalankan Kode Proyek #

Susun folder proyek berikut — setiap berkas diunduh dari bagian yang membahasnya:

text
pencarian-produk/
├── src/
│   ├── katalog-seed.js
│   ├── pencarian-teks.js
│   ├── pencarian-filter.js
│   ├── buat-index.js
│   └── uji-performa.js
└── tests/
    └── semua-tes.js

Dari folder pencarian-produk/, jalankan skrip sesuai urutan:

bash
mongosh "mongodb://127.0.0.1:27017/?directConnection=true" --file src/katalog-seed.js
mongosh "mongodb://127.0.0.1:27017/?directConnection=true" --file src/pencarian-teks.js
mongosh "mongodb://127.0.0.1:27017/?directConnection=true" --file src/pencarian-filter.js
mongosh "mongodb://127.0.0.1:27017/?directConnection=true" --file src/buat-index.js
mongosh "mongodb://127.0.0.1:27017/?directConnection=true" --file src/uji-performa.js

Untuk mengulang dari awal, jalankan kembali katalog-seed.js — database proyek_pencarian direset seluruhnya. Suite tes berjalan mandiri kapan saja karena menyiapkan datanya sendiri di database proyek_pencarian_tes:

bash
mongosh "mongodb://127.0.0.1:27017/?directConnection=true" --file tests/semua-tes.js