Pelajari cara menambahkan Meilisearch ke backend Anda untuk pencarian cepat yang toleran terhadap salah ketik: penyiapan, pengindeksan, perankingan, filter, keamanan, dan dasar penskalaan.

Pencarian server-side berarti kueri diproses di server Anda (atau layanan pencarian khusus), bukan di browser. Aplikasi Anda mengirim permintaan pencarian, server menjalankannya terhadap sebuah index, dan mengembalikan hasil yang sudah diberi peringkat.
Ini penting ketika dataset Anda terlalu besar untuk dikirim ke klien, ketika Anda membutuhkan relevansi yang konsisten antar platform, atau ketika kontrol akses tidak bisa ditawar (misalnya alat internal di mana pengguna hanya boleh melihat apa yang mereka diizinkan). Ini juga pilihan default ketika Anda menginginkan analitik, pencatatan, dan performa yang dapat diprediksi.
Orang tidak memikirkan mesin pencari—mereka menilai pengalaman. Alur pencarian “instan” yang baik biasanya berarti:
Jika salah satu ini hilang, pengguna akan mengganti kueri, menggulir lebih banyak, atau meninggalkan pencarian sepenuhnya.
Artikel ini adalah walkthrough praktis untuk membangun pengalaman tersebut dengan Meilisearch. Kita akan membahas cara menyiapkannya dengan aman, bagaimana menyusun dan menyinkronkan data yang diindeks, cara menyetel relevansi dan aturan perankingan, cara menambahkan filter/pengurutan/facet, serta cara memikirkan keamanan dan penskalaan agar pencarian tetap cepat seiring pertumbuhan aplikasi Anda.
Meilisearch cocok untuk:
Tujuannya: hasil yang terasa langsung, akurat, dan dapat dipercaya—tanpa menjadikan pencarian proyek teknik besar.
Meilisearch adalah mesin pencari yang Anda jalankan berdampingan dengan aplikasi Anda. Anda mengirim dokumen (seperti produk, artikel, pengguna, atau tiket dukungan), dan ia membangun index yang dioptimalkan untuk pencarian cepat. Backend (atau frontend) Anda lalu melakukan query ke Meilisearch melalui API HTTP sederhana dan mendapatkan hasil berperingkat dalam milidetik.
Meilisearch fokus pada fitur yang diharapkan dari pencarian modern:
Dirancang agar terasa responsif dan memaafkan, bahkan saat kueri pendek, sedikit salah, atau ambigu.
Meilisearch bukan pengganti untuk database utama Anda. Database Anda tetap sumber kebenaran untuk penulisan, transaksi, dan constraint. Meilisearch menyimpan salinan bidang yang Anda pilih untuk dijadikan searchable, filterable, atau displayable.
Model mental yang baik: database untuk menyimpan dan memperbarui data, Meilisearch untuk menemukannya dengan cepat.
Meilisearch bisa sangat cepat, tetapi hasilnya bergantung pada beberapa faktor praktis:
Untuk dataset kecil-ke-menengah, seringkali cukup dijalankan di satu mesin. Saat index tumbuh, Anda perlu lebih hati-hati tentang apa yang diindeks dan bagaimana Anda memperbaruinya—topik yang akan kita bahas di bagian selanjutnya.
Sebelum memasang apa pun, putuskan apa yang sebenarnya akan Anda cari. Meilisearch terasa “instan” hanya jika index dan dokumen Anda cocok dengan cara orang menelusuri aplikasi Anda.
Mulailah dengan daftar entitas yang dapat dicari—biasanya products, articles, users, help docs, locations, dll. Dalam banyak aplikasi, pendekatan paling bersih adalah satu index per tipe entitas (mis. products, articles). Itu menjaga aturan perankingan dan filter tetap dapat diprediksi.
Jika UX Anda mencari di banyak tipe dalam satu kotak (“cari semuanya”), Anda masih bisa menjaga index terpisah dan menggabungkan hasil di backend, atau membuat index “global” khusus nanti. Jangan memaksa semuanya ke satu index kecuali field dan filter benar-benar selaras.
Setiap dokumen membutuhkan pengenal stabil (primary key). Pilih sesuatu yang:
id, sku, slug)Untuk bentuk dokumen, lebih suka field datar bila memungkinkan. Struktur datar lebih mudah untuk filter dan sort. Field bersarang (nested) baik jika mewakili bundel yang ketat dan tidak berubah (mis. objek author), tetapi hindari nesting yang dalam yang meniru seluruh skema relasional Anda—dokumen pencarian sebaiknya dioptimalkan untuk baca, bukan berbentuk database.
Cara praktis mendesain dokumen adalah menandai setiap field dengan satu peran:
Ini mencegah kesalahan umum: mengindeks field “hanya untuk berjaga-jaga” dan kemudian bertanya-tanya mengapa hasilnya berisik atau filter lambat.
“Bahasa” bisa berarti hal berbeda dalam data Anda:
lang: "en")Putuskan lebih awal apakah Anda akan menggunakan index terpisah per bahasa (sederhana dan dapat diprediksi) atau satu index dengan field bahasa (lebih sedikit index, logika lebih kompleks). Jawaban yang tepat bergantung pada apakah pengguna mencari dalam satu bahasa pada satu waktu dan bagaimana Anda menyimpan terjemahan.
Menjalankan Meilisearch sederhana, tetapi "aman secara default" membutuhkan beberapa pilihan yang disengaja: dimana Anda menerapkannya, bagaimana Anda menyimpan data, dan bagaimana menangani master key.
Penyimpanan: Meilisearch menulis index ke disk. Letakkan direktori data di penyimpanan yang andal dan persisten (bukan penyimpanan kontainer yang ephemeral). Rencanakan kapasitas untuk pertumbuhan: index dapat membesar dengan cepat pada field teks besar dan banyak atribut.
Memori: alokasikan RAM yang cukup agar pencarian tetap responsif di bawah beban. Jika Anda melihat swapping, performa akan menurun.
Backup: backup direktori data Meilisearch (atau gunakan snapshot di lapisan penyimpanan). Uji pemulihan setidaknya sekali; backup yang tidak bisa dipulihkan hanyalah file biasa.
Monitoring: pantau CPU, RAM, penggunaan disk, dan I/O disk. Juga pantau kesehatan proses dan log error. Minimal, beri alert jika layanan berhenti atau ruang disk menipis.
Selalu jalankan Meilisearch dengan master key pada apa pun selain pengembangan lokal. Simpan di secret manager atau penyimpanan variabel lingkungan terenkripsi (jangan di Git, jangan di .env biasa yang dikomit ke repo).
Contoh (Docker):
docker run -d --name meilisearch \\
-p 7700:7700 \\
-v meili_data:/meili_data \\
-e MEILI_MASTER_KEY="$(openssl rand -hex 32)" \\
getmeili/meilisearch:latest
Juga pertimbangkan aturan jaringan: bind ke interface privat atau batasi akses masuk sehingga hanya backend Anda yang dapat menjangkau Meilisearch.
curl -s http://localhost:7700/version
Pengindeksan Meilisearch bersifat asinkron: Anda mengirim dokumen, Meilisearch mengantri sebuah task, dan hanya setelah task itu berhasil dokumen akan menjadi dapat dicari. Perlakukan pengindeksan seperti sistem job, bukan satu permintaan tunggal.
id).curl -X POST 'http://localhost:7700/indexes/products/documents?primaryKey=id' \\
-H 'Content-Type: application/json' \\
-H 'Authorization: Bearer YOUR_WRITE_KEY' \\
--data-binary @products.json
taskUid. Poll sampai statusnya succeeded (atau failed).curl -X GET 'http://localhost:7700/tasks/123' \\
-H 'Authorization: Bearer YOUR_WRITE_KEY'
curl -X GET 'http://localhost:7700/indexes/products/stats' \\
-H 'Authorization: Bearer YOUR_WRITE_KEY'
Jika jumlah tidak cocok, jangan menebak—periksa detail error task terlebih dahulu.
Batching soal menjaga task tetap dapat diprediksi dan dapat dipulihkan.
addDocuments berperilaku seperti upsert: dokumen dengan primary key yang sama akan diperbarui, yang baru akan disisipkan. Gunakan ini untuk pembaruan normal.
Lakukan reindex penuh ketika:
Untuk penghapusan, panggil deleteDocument(s) secara eksplisit; jika tidak, record lama bisa tetap tersisa.
Pengindeksan harus bisa di-retry. Kuncinya adalah id dokumen yang stabil.
taskUid yang dikembalikan bersama id batch/job Anda, dan retry berdasarkan status task.Sebelum data produksi, indeks dataset kecil (200–500 item) yang cocok dengan field nyata Anda. Contoh: set products dengan id, name, description, category, brand, price, inStock, createdAt. Ini cukup untuk memvalidasi alur task, jumlah, dan perilaku update/delete—tanpa menunggu impor besar.
“Relevansi” pencarian hanyalah: apa yang muncul pertama, dan kenapa. Meilisearch membuatnya dapat disesuaikan tanpa memaksa Anda membangun sistem scoring sendiri.
Dua pengaturan membentuk apa yang bisa dilakukan Meilisearch dengan konten Anda:
searchableAttributes: field yang dicari saat pengguna mengetik kueri (mis. title, summary, tags). Urutan penting: field yang lebih awal dianggap lebih penting.displayedAttributes: field yang dikembalikan di respons. Ini penting untuk privasi dan ukuran payload—jika field tidak ditampilkan, field itu tidak akan dikirim kembali.Baseline praktis adalah membuat beberapa field sinyal-tinggi menjadi searchable (title, teks kunci), dan batasi displayed fields ke apa yang UI butuhkan.
Meilisearch mengurutkan dokumen yang cocok menggunakan ranking rules—sebuah pipeline "tie-breaker." Secara konseptual, ia memprioritaskan:
Anda tidak perlu menghafal internals untuk menyetelnya secara efektif; Anda terutama memilih field mana yang penting dan kapan menerapkan pengurutan custom.
Tujuan: “Kecocokan judul harus menang.” Letakkan title di awal:
{
"searchableAttributes": ["title", "subtitle", "description", "tags"]
}
Tujuan: “Konten yang lebih baru muncul dulu.” Tambahkan aturan sort dan minta sort di waktu query (atau set ranking custom):
{
"sortableAttributes": ["publishedAt"],
"rankingRules": ["sort", "typo", "words", "proximity", "attribute", "exactness"]
}
Lalu request:
{ "q": "release notes", "sort": ["publishedAt:desc"] }
Tujuan: “Promosikan item populer.” Jadikan popularity sortable dan urutkan berdasarkan itu saat tepat.
Pilih 5–10 kueri nyata pengguna. Simpan hasil teratas sebelum perubahan, lalu bandingkan sesudah.
Contoh:
"apple" → Apple Watch band, Pineapple slicer, Apple iPhone case"apple" → Apple iPhone case, Apple Watch band, Pineapple slicerJika daftar “sesudah” lebih cocok dengan niat pengguna, pertahankan pengaturan. Jika merusak kasus tepi, ubah satu hal pada satu waktu (urutan atribut, lalu aturan pengurutan) sehingga Anda tahu apa yang menyebabkan perbaikan.
Kotak pencarian yang baik bukan sekadar "ketik kata, dapat kecocokan." Orang juga ingin mempersempit hasil ("hanya item yang tersedia") dan mengurutkannya ("termurah dulu"). Di Meilisearch, Anda melakukan ini dengan filters, sorting, dan facets.
Filter adalah aturan yang Anda terapkan pada hasil. Facet adalah apa yang Anda tunjukkan di UI untuk membantu pengguna membentuk aturan itu (sering sebagai checkbox atau hitungan).
Contoh non-teknis:
Jadi pengguna mungkin mencari “running” lalu memfilter ke category = Shoes dan status = in_stock. Facet dapat menunjukkan hitungan seperti “Shoes (128)” dan “Jackets (42)” sehingga pengguna tahu apa yang tersedia.
Meilisearch membutuhkan Anda secara eksplisit mengizinkan field yang dipakai untuk filtering dan pengurutan.
category, status, brand, price, created_at (jika Anda memfilter berdasarkan waktu), tenant_id (jika Anda mengisolasi pelanggan).price, rating, created_at, popularity.Jaga daftar ini ketat. Membuat semuanya filterable/sortable dapat meningkatkan ukuran index dan memperlambat pembaruan.
Bahkan jika Anda punya 50.000 kecocokan, pengguna hanya melihat halaman pertama. Gunakan halaman kecil (sering 20–50 hasil), set limit yang masuk akal, dan paginasi dengan offset (atau fitur paginasi baru jika Anda suka). Juga batasi kedalaman halaman maksimum di aplikasi Anda untuk mencegah permintaan mahal seperti “halaman 400”.
Cara bersih menambahkan pencarian server-side adalah memperlakukan Meilisearch sebagai layanan data khusus di balik API Anda. Aplikasi menerima permintaan pencarian, memanggil Meilisearch, lalu mengembalikan respons yang dikurasi ke klien.
Sebagian besar tim berakhir dengan alur seperti ini:
GET /api/search?q=wireless+headphones&limit=20).Pola ini menjaga Meilisearch bisa diganti dan mencegah kode frontend bergantung pada internals index.
Jika Anda membangun aplikasi baru (atau membangun ulang alat internal) dan ingin pola ini cepat diimplementasikan, platform vibe-coding seperti Koder.ai bisa membantu men-scaffold alur penuh—UI React, backend Go, dan PostgreSQL—lalu mengintegrasikan Meilisearch di balik endpoint tunggal /api/search sehingga klien tetap sederhana dan permissions tetap di sisi server.
Meilisearch mendukung query dari klien, tetapi query lewat backend biasanya lebih aman karena:
Query frontend masih bisa bekerja untuk data publik dengan kunci terbatas, tetapi jika Anda punya aturan visibilitas per pengguna, rute pencarian lewat server Anda.
Traffic pencarian sering berulang (“iphone case”, “return policy”). Tambahkan caching di lapisan API Anda:
Perlakukan pencarian sebagai endpoint publik:
limit maksimum dan panjang kueri maksimum.Meilisearch sering ditempatkan “di balik” aplikasi Anda karena bisa mengembalikan data bisnis sensitif dengan cepat. Perlakukan seperti database: kunci akses, dan expose hanya apa yang seharusnya dilihat tiap pemanggil.
Meilisearch punya master key yang bisa melakukan semuanya: buat/hapus index, update settings, dan baca/tulis dokumen. Simpan master key di server saja.
Untuk aplikasi, buat API key dengan aksi terbatas dan index terbatas. Pola umum:
Least privilege berarti key yang bocor tidak bisa menghapus data atau membaca index lain.
Jika Anda melayani banyak pelanggan (tenant), ada dua opsi utama:
1) Satu index per tenant.
Sederhana untuk dipahami dan mengurangi risiko akses silang tenant. Kekurangannya: lebih banyak index untuk dikelola, dan update settings harus diterapkan konsisten.
2) Index bersama + filter tenant.
Simpan field tenantId pada setiap dokumen dan wajibkan filter seperti tenantId = "t_123" untuk semua pencarian. Ini bisa skala dengan baik, tetapi pastikan setiap permintaan selalu menerapkan filter (idealnya via key scoped sehingga pemanggil tidak bisa menghapusnya).
Bahkan jika pencarian benar, hasil bisa membocorkan field yang tidak Anda maksudkan muncul (email, catatan internal, harga pokok). Konfigurasikan apa yang bisa dikembalikan:
Lakukan tes “worst-case”: cari istilah umum dan pastikan tidak ada field privat muncul.
Jika Anda ragu apakah sebuah key boleh di-klien, anggap "tidak" dan jaga pencarian di sisi server.
Meilisearch cepat ketika Anda menjaga dua beban kerja dalam pikiran: pengindeksan (penulisan) dan query pencarian (pembacaan). Kebanyakan "lambat misterius" biasanya salah satu dari keduanya bersaing untuk CPU, RAM, atau disk.
Beban pengindeksan bisa melonjak saat Anda mengimpor batch besar, menjalankan pembaruan sering, atau menambah banyak field searchable. Pengindeksan adalah tugas latar, tetapi tetap menggunakan CPU dan bandwidth disk. Jika antrean task menumpuk, pencarian bisa terasa lebih lambat meski volume query tidak berubah.
Beban query tumbuh dengan traffic, tetapi juga dengan fitur: lebih banyak filter, lebih banyak facet, set hasil lebih besar, dan toleransi salah ketik bisa meningkatkan kerja per permintaan.
I/O disk sering jadi penyebab sunyi. Disk lambat (atau tetangga bising pada volume bersama) bisa mengubah “instan” menjadi “nanti”. NVMe/SSD adalah baseline tipikal untuk produksi.
Mulailah dengan sizing sederhana: beri Meilisearch cukup RAM untuk menjaga index tetap hot dan cukup CPU untuk menangani peak QPS. Kemudian pisahkan kekhawatiran:
Pantau beberapa sinyal kecil:
Backup harus rutin, bukan heroik. Gunakan fitur snapshot Meilisearch sesuai jadwal, simpan snapshot di luar box, dan uji pemulihan berkala. Untuk upgrade, baca release notes, stage upgrade di environment non-prod, dan rencanakan waktu reindex jika versi mempengaruhi perilaku pengindeksan.
Jika Anda sudah menggunakan snapshot lingkungan dan rollback di platform aplikasi Anda (mis. lewat workflow snapshots/rollback Koder.ai), selaraskan rollout pencarian dengan disiplin yang sama: snapshot sebelum perubahan, verifikasi health checks, dan jaga jalur cepat kembali ke kondisi baik sebelumnya.
Bahkan dengan integrasi bersih, masalah pencarian cenderung jatuh pada beberapa kategori berulang. Kabar baik: Meilisearch memberi visibilitas cukup (tasks, logs, settings deterministik) untuk men-debug cepat—jika Anda mendekatinya secara sistematis.
filterableAttributes, atau dokumen menyimpannya dalam bentuk yang tak terduga (string vs array vs nested object).sortableAttributes/rankingRules membuat item “salah” muncul di atas.Mulai dengan memeriksa apakah Meilisearch berhasil menerapkan perubahan terakhir Anda.
filter, lalu sort, lalu facets.Jika Anda tidak bisa menjelaskan sebuah hasil, sementara waktu kembalikan konfigurasi: hapus sinonim, kurangi tweak ranking, dan uji dengan dataset kecil. Masalah relevansi kompleks lebih mudah ditemukan pada 50 dokumen daripada pada 5 juta.
your_index_v2 paralel, terapkan settings, dan replay sampel query produksi.filterableAttributes dan sortableAttributes cocok dengan kebutuhan UI Anda.Related guides: /blog (search reliability, indexing patterns, and production rollout tips).
Pencarian sisi-server berarti kueri dijalankan di backend Anda (atau layanan pencarian khusus), bukan di browser. Ini pilihan yang tepat ketika:
Pengguna langsung memperhatikan empat hal:
Jika salah satu hilang, orang akan mengetik ulang, menggulir berlebihan, atau meninggalkan pencarian.
Anggap Meilisearch sebagai indeks pencarian, bukan sumber kebenaran. Database Anda tetap menangani penulisan, transaksi, dan batasan; Meilisearch menyimpan salinan bidang terpilih yang dioptimalkan untuk pengambilan cepat.
Model mental yang berguna:
Default yang umum adalah satu index per tipe entitas (mis. products, articles). Ini menjaga:
Jika Anda butuh “cari semuanya”, Anda bisa menanyakan beberapa index dan menggabungkan hasil di backend, atau menambahkan index global khusus nanti.
Pilih primary key yang:
id, sku, slug)ID yang stabil membuat pengindeksan menjadi idempoten: jika Anda mengulang upload, Anda tidak akan membuat duplikat karena update menjadi upsert yang aman.
Klasifikasikan setiap field dengan tujuan agar Anda tidak mengindeks berlebihan:
Menjaga peran ini eksplisit mengurangi hasil noisy dan mencegah index yang lambat atau bengkak.
Pengindeksan bersifat asinkron: upload dokumen membuat sebuah tugas, dan dokumen menjadi dapat dicari hanya setelah tugas itu berhasil.
Alur andal:
succeeded atau failedGunakan banyak batch kecil daripada satu upload besar. Titik awal praktis:
Batch kecil lebih mudah di-retry, lebih mudah di-debug (mencari record buruk), dan lebih kecil kemungkinan timeout.
Dua tuas berdampak besar:
searchableAttributes: field mana yang dicari, dan urutannya (prioritas)publishedAt, price, atau popularityPendekatan praktis: ambil 5–10 kueri nyata pengguna, simpan hasil teratas “sebelum”, ubah satu pengaturan, lalu bandingkan “sesudah.”
Sebagian besar masalah filter/sort berasal dari konfigurasi yang hilang:
filterableAttributes agar bisa difiltersortableAttributes agar bisa diurutkanJuga periksa bentuk dan tipe field di dokumen (string vs array vs nested object). Jika filter gagal, periksa status task terakhir dan pastikan dokumen terindeks berisi nilai field yang diharapkan.
statsJika hasil terlihat kadaluwarsa, periksa status tugas sebelum men-debug hal lain.