Gratis update & dukungan instalasi

Tutorial Website 21 Oct 2026

Cara Membuat Fitur Pencarian Produk di Laravel: dari LIKE ke Full-Text Search (Panduan 2026)

R Oleh renz mobellgnd
Cara Membuat Fitur Pencarian Produk di Laravel: dari LIKE ke Full-Text Search (Panduan 2026)

Cara Membuat Fitur Pencarian Produk di Laravel: dari LIKE ke Full-Text Search (Panduan 2026)

Fitur pencarian produk di Laravel bisa dibuat dalam 3 level: LIKE untuk pencarian sederhana, full-text search MySQL lewat whereFullText untuk hasil yang lebih cepat dan terurut relevansi, dan Laravel Scout untuk kebutuhan skala besar. Untuk toko online dengan ribuan produk, full-text search adalah titik tengah terbaik — tanpa layanan eksternal, tanpa biaya tambahan.

Pengalaman saya membangun dan memodifikasi beberapa source code toko online: kolom pencarian adalah fitur yang paling sering dikeluhkan pembeli source code. Bukan karena tidak ada, tapi karena lambat atau hasilnya "bodoh" — mencari "sepatu lari" malah menampilkan produk yang tidak relevan. Artikel ini membahas ketiga level pencarian beserta jebakan yang jarang ditulis tutorial lain, supaya kamu bisa memilih yang pas untuk kebutuhanmu.

Apa Itu Pencarian Produk yang Baik?

Pencarian produk yang baik memenuhi tiga syarat: cepat (hasil muncul di bawah 1 detik untuk puluhan ribu data), relevan (produk paling cocok tampil paling atas), dan toleran (tetap menemukan hasil walau ejaan pengguna tidak sempurna). LIKE hanya memenuhi syarat pertama untuk data kecil. Full-text search memenuhi dua syarat pertama. Untuk syarat ketiga, kamu perlu mesin pencari khusus seperti Meilisearch.

3 Level Pencarian di Laravel: Perbandingan Cepat

Aspek LIKE Full-Text (MySQL) Laravel Scout
Cara kerjaPencocokan substring %kata%Indeks kata + skor relevansi (MATCH AGAINST)Indeks eksternal (Meilisearch/Algolia/database)
Urutan hasilUrutan database (acak/tidak relevan)Terurut skor relevansi otomatisTerurut relevansi + typo tolerance
Kecepatan (100rb baris)Lambat (full table scan)Cepat (pakai indeks)Sangat cepat
Infrastruktur tambahanTidak adaTidak ada (bawaan MySQL/MariaDB)Perlu service/driver tambahan
Cocok untukData kecil, kolom pendek (SKU, kode)Toko online menengah, blog, katalogMarketplace besar, pencarian kompleks

Sumber dokumentasi resmi: Laravel 12.x — Full-Text Search dan Query Builder — whereFullText.

Level 1: Pencarian dengan LIKE (Titik Awal yang Wajar)

Untuk katalog di bawah seribu produk, LIKE sudah cukup dan paling mudah. Pola standarnya begini:

// app/Http/Controllers/ProductController.php
public function search(Request $request)
{
$keyword = $request->input('q');

$products = Product::query()
->where('is_active', true)
->when($keyword, function ($query, $keyword) {
$query->where(function ($q) use ($keyword) {
$q->where('name', 'like', "%{$keyword}%")
->orWhere('description', 'like', "%{$keyword}%")
->orWhere('sku', 'like', "%{$keyword}%");
});
})
->latest()
->paginate(12)
->withQueryString();

return view('products.index', compact('products'));
}

Kelemahan LIKE yang harus kamu tahu:

  1. Tidak memakai indeks. Pola %kata% (wildcard di depan) memaksa MySQL memindai seluruh tabel. Di 100.000 baris, satu pencarian bisa memakan waktu beberapa detik.
  2. Tidak mengerti relevansi. Produk yang namanya persis "sepatu lari" bisa muncul di bawah produk yang deskripsinya kebetulan menyebut kata "sepatu" di paragraf terakhir.
  3. Tidak mengerti bahasa. Mencari "berlari" tidak akan menemukan "lari".

Kalau kamu memakai LIKE, pastikan tetap dikombinasikan dengan filter kategori dan pagination seperti contoh di atas — itu pola yang dipakai banyak source code toko online siap pakai, termasuk pola ProductSearchService yang populer di tutorial BuildWithAngga.

Level 2: Full-Text Search MySQL dengan whereFullText

Ini level yang paling jarang dibahas tuntas di tutorial Indonesia, padahal didukung penuh Laravel sejak lama dan tidak butuh layanan tambahan. MySQL/MariaDB/PostgreSQL sudah punya mesin full-text search bawaan.

Langkah 1: Tambahkan full-text index di migration

Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('description');
$table->string('sku')->unique();
$table->timestamps();

$table->fullText(['name', 'description']);
});

Untuk tabel yang sudah ada, buat migration baru:

php artisan make:migration add_fulltext_index_to_products_table
public function up(): void
{
Schema::table('products', function (Blueprint $table) {
$table->fullText(['name', 'description']);
});
}

Langkah 2: Pakai whereFullText di controller

public function search(Request $request)
{
$keyword = $request->input('q');

$products = Product::query()
->where('is_active', true)
->when($keyword, function ($query, $keyword) {
$query->whereFullText(['name', 'description'], $keyword);
})
->latest()
->paginate(12)
->withQueryString();

return view('products.index', compact('products'));
}

Laravel menerjemahkannya menjadi MATCH(name, description) AGAINST(? IN NATURAL LANGUAGE MODE) di MySQL — dengan skor relevansi bawaan, sehingga produk paling cocok otomatis tampil paling atas. Untuk mode pencarian yang lebih presisi, ada dua opsi tambahan (lihat cheat-sheet Laravel Daily):

// Boolean mode: wajib ada "sepatu", tidak boleh ada "bekas"
Product::whereFullText(['name', 'description'], '+sepatu -bekas', ['mode' => 'boolean'])->get();

// Query expansion: cari juga kata-kata terkait dari hasil teratas
Product::whereFullText(['name', 'description'], 'sneakers', ['expanded' => true])->get();

5 Jebakan Full-Text Search yang Jarang Dibahas

Inilah bagian yang membedakan artikel ini dari tutorial lain — hal-hal yang baru ketahuan setelah implementasi di proyek nyata:

  1. Kata di bawah 3 karakter tidak terindeks (InnoDB). Pengaturan bawaan innodb_ft_min_token_size = 3 berarti pencarian "HP" (handphone) atau "TV" tidak akan menemukan apa-apa lewat full-text. Solusinya: untuk SKU dan kode pendek, tetap sediakan fallback LIKE khusus kolom sku.
  2. Stopword diabaikan. Kata umum seperti "dan", "yang", "dengan" otomatis dilewati MySQL. Ini biasanya menguntungkan, tapi jangan heran kalau tidak berpengaruh di hasil.
  3. Tidak ada stemming bahasa Indonesia. Mencari "berlari" tidak menemukan "lari", dan "termurah" tidak menemukan "murah". Ini keterbatasan bawaan MySQL, bukan bug di kodemu.
  4. Case-insensitive secara default. "Sepatu" dan "sepatu" dianggap sama — kabar baik untuk pengguna Indonesia yang malas pakai huruf kapital.
  5. Hasil bisa kosong di testing. Full-text index di MySQL tidak selalu ter-update sinkron saat memakai RefreshDatabase di test — gejala yang sempat membingungkan banyak developer (dibahas di komunitas DEV). Untuk test pencarian, pakai database MySQL asli, bukan SQLite in-memory.

Poin 1–3 adalah alasan kenapa pola terbaik untuk toko online adalah kombinasi: LIKE untuk SKU/kode produk + whereFullText untuk nama dan deskripsi.

Level 3: Laravel Scout (Saatnya Naik Kelas)

Naik ke Scout ketika: katalog di atas 100 ribu produk, butuh typo tolerance ("sepatu" tetap ketemu walau diketik "sepatuu"), atau butuh pencarian instan saat mengetik (autocomplete). Sejak Laravel 12, Scout punya database engine bawaan yang bekerja tanpa layanan eksternal:

use Laravel\Scout\Attributes\SearchUsingFullText;
use Laravel\Scout\Attributes\SearchUsingPrefix;
use Laravel\Scout\Searchable;

class Product extends Model
{
use Searchable;

#[SearchUsingFullText(['name', 'description'])]
#[SearchUsingPrefix(['sku'])]
public function toSearchableArray(): array
{
return [
'name' => $this->name,
'description' => $this->description,
'sku' => $this->sku,
];
}
}

Dengan atribut di atas, kolom name/description memakai full-text index database, sedangkan sku memakai pencocokan awalan (sku%) — elegan dan menyelesaikan jebakan poin 1 di atas. Ketika kebutuhan bertambah, ganti driver ke Meilisearch tanpa mengubah kode pencarianmu.

Tips Performa: Bikin Pencarian Produk Makin Ngebut

  1. Indeks dulu, optimasi kemudian. Full-text index adalah fondasi; tanpa itu, optimasi lain sia-sia. Prinsip indexing ini sama dengan yang dibahas di artikel cara optimasi database MySQL.
  2. Cache kata kunci populer. 20% kata kunci biasanya menghasilkan 80% pencarian. Cache hasil pencarian populer selama 10–60 menit dengan Cache::remember — teknik caching ini bagian dari 10 cara mempercepat website Laravel.
  3. Batasi kolom yang di-select. Jangan SELECT * untuk halaman hasil pencarian; ambil hanya id, name, slug, price, image.
  4. Sediakan endpoint API untuk autocomplete. Kalau tokomu juga punya aplikasi mobile, sediakan endpoint /api/products/search?q=... yang ringan — pola REST API-nya sama seperti di panduan REST API Laravel untuk aplikasi mobile.
  5. Pisahkan pencarian admin dan publik. Pencarian di dashboard admin (berdasarkan SKU, nama pembeli) kebutuhannya beda dengan pencarian pengunjung — jangan paksakan satu query untuk dua kebutuhan.

Kapan Cara Ini Tidak Cocok?

Jujur saja: full-text search MySQL bukan solusi untuk semua kasus. Jangan pakai whereFullText jika kamu butuh pencarian lintas banyak tabel sekaligus dengan join kompleks (skor relevansi jadi sulit diprediksi), butuh typo tolerance yang serius (pakai Meilisearch/Typesense), atau database-mu bukan MySQL/MariaDB/PostgreSQL (misalnya SQLite untuk testing — pahami batasannya seperti dibahas di atas). Untuk kebutuhan itu, Laravel Scout dengan driver khusus adalah jalan yang benar sejak awal.

FAQ

Apa perbedaan LIKE dan full-text search di Laravel? LIKE mencocokkan substring (%kata%) tanpa memahami relevansi dan tidak memakai indeks saat wildcard di depan. Full-text search memakai indeks kata khusus (MATCH AGAINST) sehingga lebih cepat untuk data besar dan hasilnya terurut berdasarkan skor relevansi.

Bagaimana cara menambahkan full-text index di Laravel? Tambahkan $table->fullText(['kolom1', 'kolom2']); di migration, lalu jalankan php artisan migrate. Setelah itu gunakan whereFullText(['kolom1', 'kolom2'], $keyword) di query.

Apakah whereFullText bisa dipakai di shared hosting? Bisa, selama database-nya MySQL 5.6+ atau MariaDB 10.0.5+ dengan engine InnoDB — yang hampir selalu tersedia di shared hosting Indonesia. Tidak perlu install apa pun di server.

Kenapa pencarian "HP" tidak menemukan produk handphone? Karena InnoDB tidak mengindeks kata di bawah 3 karakter (innodb_ft_min_token_size = 3). Solusinya: tambahkan kondisi LIKE khusus untuk kolom SKU/kode, atau gunakan atribut SearchUsingPrefix di Laravel Scout.

Apakah full-text search mendukung bahasa Indonesia? Bisa dipakai, tapi tanpa stemming: "berlari" tidak akan menemukan "lari". Untuk kebutuhan stemming dan typo tolerance bahasa Indonesia, gunakan Meilisearch via Laravel Scout.

Kapan harus pakai Laravel Scout, bukan whereFullText? Saat katalog di atas 100 ribu produk, butuh typo tolerance, atau butuh fitur seperti autocomplete instan dan faceted search. Scout versi terbaru bahkan punya database engine bawaan sehingga bisa dicoba tanpa layanan eksternal.

Apakah full-text search memperlambat proses insert/update produk? Ada overhead kecil karena indeks harus di-update, tapi untuk toko online tipikal (baca jauh lebih sering daripada tulis) dampaknya tidak terasa. Pola ini sejalan dengan praktik terbaik update produk dan kategori.

Pencarian produk yang baik bukan soal teknologi paling canggih, tapi soal memilih level yang pas: LIKE untuk awal, full-text search MySQL untuk toko yang bertumbuh, Scout untuk skala besar. Kalau kamu membeli source code toko online, cek dulu level berapa pencarian bawaannya — karena mengganti fondasi pencarian di tengah jalan jauh lebih mahal daripada memilih yang tepat sejak awal.