Fitur pencarian di blog kelihatannya sepele. Tapi kalau dipikir lebih dalam, ada beberapa pendekatan yang bisa diambil — dan masing-masing punya trade-off yang berbeda. Di artikel ini saya ceritakan bagaimana saya membangun fitur pencarian di kawunganten.com, dari yang paling kasar sampai ke versi yang sekarang berjalan.
Versi Pertama: LIKE yang Polos
Versi paling awal dari fitur pencarian blog ini pakai query LIKE standar MySQL. Begini kira-kira logikanya:
SELECT id, title, slug FROM posts
WHERE title LIKE ? OR content LIKE ?
ORDER BY created_at DESC;
Di mana tanda tanya diisi dengan %kata_kunci% — tanda persen di kiri dan kanan artinya cari kata kunci itu di mana saja dalam string, bukan harus di awal atau akhir.
Ini jalan. Tapi ada masalah yang muncul cepat: pencarian terlalu literal. Kalau pengunjung cari "optimasi mysql", tapi artikel saya judulnya "Cara Mengoptimalkan Query MySQL", hasilnya tidak muncul. Padahal temanya sama. LIKE mencari kecocokan karakter per karakter — tidak paham konteks, tidak paham sinonim, tidak paham kata dasar.
Masalah lain: pencarian di kolom content yang isinya HTML itu tidak bersih. Kata kunci yang sebenarnya ada dalam teks bisa ketinggalan karena diapit tag HTML, atau sebaliknya, hasil match yang muncul karena kata kuncinya kebetulan ada di dalam nama class CSS.
Versi Kedua: Full-Text Search MySQL
MySQL punya fitur built-in bernama Full-Text Search yang jauh lebih pintar dari LIKE. Untuk memakainya, kita perlu tambahkan FULLTEXT index ke kolom yang ingin dicari:
ALTER TABLE posts ADD FULLTEXT INDEX ft_search (title, content);
Lalu querynya jadi:
SELECT id, title, slug,
MATCH(title, content) AGAINST(? IN BOOLEAN MODE) AS relevance
FROM posts
WHERE MATCH(title, content) AGAINST(? IN BOOLEAN MODE)
ORDER BY relevance DESC;
Boolean mode memberi kita lebih banyak kontrol — bisa pakai operator seperti + untuk kata yang wajib ada, - untuk kata yang harus tidak ada, dan tanda bintang untuk prefix matching. Lebih powerful dari LIKE.
Hasilnya jauh lebih baik. Relevansi hasil pencarian meningkat, dan kecepatannya pun lebih bagus karena FULLTEXT index memang dioptimasi untuk pencarian teks.
Tapi masih ada satu masalah: konten di database menyimpan HTML mentah. Jadi kalau isi artikel ada tag <strong>optimasi</strong>, kata "optimasi" tetap ditemukan — itu bagus. Tapi kadang ada karakter entitas HTML yang ikut masuk ke pencarian dengan cara yang tidak diinginkan.
Solusi: Strip HTML Sebelum Masuk Database
Idealnya, saya punya kolom tersendiri yang menyimpan versi plain text dari konten — tanpa tag HTML, tanpa entitas. Kolom itu yang dipakai untuk pencarian, sementara konten asli (dengan HTML) tetap ada untuk ditampilkan.
Ini yang akhirnya saya implementasikan. Setiap kali artikel disimpan atau diperbarui, saya jalankan strip_tags() dan html_entity_decode() di PHP, lalu simpan hasilnya ke kolom content_plain. FULLTEXT index kemudian dibuat di kolom judul dan content_plain ini.
Hasilnya lebih bersih dan lebih akurat.
Highlight Kata Kunci di Hasil Pencarian
Satu fitur kecil yang lumayan meningkatkan pengalaman pengguna adalah highlight kata kunci di cuplikan hasil pencarian. Jadi pengunjung bisa langsung lihat di mana kata yang mereka cari muncul dalam artikel.
Caranya sederhana: ambil potongan teks di sekitar kata kunci yang ditemukan, lalu bungkus kata kuncinya dengan tag <mark> atau <strong>. Pakai regex di PHP untuk menemukan posisinya, ambil sekitar 150 karakter sebelum dan sesudahnya sebagai cuplikan.
Terlihat kecil, tapi feedback dari pengunjung yang bilang fitur pencarian blog ini "enak dipakai" — itu cukup memotivasi untuk terus dipoles.
Yang Belum Saya Selesaikan
Full-text search MySQL tidak paham stemming untuk bahasa Indonesia. Artinya pencarian "mengoptimalkan" tidak akan menemukan artikel yang isinya pakai kata "optimasi" — padahal kata dasarnya sama. Untuk ini sebetulnya ada solusi lebih canggih seperti Elasticsearch yang bisa dikonfigurasi untuk bahasa Indonesia, tapi itu overkill untuk blog seukuran ini.
Untuk sekarang, saya tambahkan daftar sinonim manual dan beberapa kata umum yang sering dicari — solusi sederhana yang tidak sempurna tapi cukup untuk kebutuhan sekarang.
Pernah membangun fitur pencarian juga? Atau ada pendekatan lain yang pernah kamu coba? Saya tertarik banget untuk diskusi di komentar.
Belum ada komentar. Jadilah yang pertama menulis.
Tulis Komentar