Fuse.js merupakan library javascript pencarian fuzzy yang sering saya gunakan untuk membuat fitur pencarian dari sebuah data json. Library ini memiliki kelebihan, sebagai berikut.
- Bisa mengatur threshold atau tingkat toleransi
- Pencocokan multi kata, sehingga mampu mencari beberapa kata sekaligus
- Pencarian bebas typo, artinya pengguna tidak perlu menuliskan persis nama item yang ingin dituju
- Libray yang ringan untuk digunakan, apalagi data yang dimiliki sangat banyak
Instalasi
Untuk instalasi sangat mudah, sesuaikan dengan package manager yang dimiliki, NPM/BUN/PNPM/YARN. Disini saya menggunakan NPM saja yang paling umum digunakan.
npm i fuse.js
Persiapan
Karena ini cuman percobaan saja, saya akan menjalankannya pakai node.js, teman - teman bisa menggunakan fuse.js di project Vue, React, Next.js maupun Svelte.
├── node_modules
├── blogs.js
├── index.js
├── package-lock.json
├── package.json
└── ...
Source code bisa dilihat di @github/fuzzy-search-fusejs.
Data Blog
blogs.js sebagai data percobaan untuk melakukan pencarian suatu keyword.
const blogs = [
{
title: 'Belajar Next.js untuk Pemula',
descriptions: 'Panduan dasar untuk memulai dengan Next.js.',
categories: ['Next.js', 'JavaScript', 'Frontend'],
created_at: '2024-03-01',
updated_at: '2024-03-05'
},
...
];
export default blogs;
Cara Penggunaan
Memanggil Library
Tentu hal yang pertama dilakukan yaitu memanggil library
import Fuse from "fuse.js";
Initial
Fuse merupakan object class yang harus dipanggil menggunakan new.
import Fuse from "fuse.js";
const fuse = new Fuse();
Skema
YOUR_DATA_JSON merupakan data yang sudah disiapkan seperti contoh blogs.js
. KONFIGURASI berisi banyak property untuk mengatur bagaimana cara Fuse melakukan pencarian yang kita mau.
import Fuse from "fuse.js";
const fuse = new Fuse(YOUR_DATA_JSON, { KONFIGURASI });
Mengenal Property untuk Konfigurasi
Ada banyak property didalam Fuse, tapi saya akan jelasin property yang sering digunakan saja.
import Fuse from "fuse.js";
const fuse = new Fuse(YOUR_DATA_JSON, {
keys: [],
includeScore: false,
threshold: 0,
minMatchCharLength: 3,
});
- keys
string[]
Menentukan properti dalam objek data yang akan digunakan untuk pencarian. Di fileblogs.js
memiliki banyak property mulai dari title, descriptions, categories, created_at, updated_at. Kita bisa melakukan konfigurasi agar Fuse hanya mencarititle
,descriptions
,categories
saja. - includeScore
boolean
Property ini hanya bisa diisi dengantrue
ataufalse
saja. Jikatrue
maka skor kesamaan (similrity score) akan disertakan pada hasil pencarian. 0 berarti cocok sempurna dan 1 berarti tidak cocok sama sekali. - threshold
number
Menentukan sensitifitas kecocokan hanya bisa diisi 0-1.
0 berarti hanya hasil yang benar-benar cocok atau mirip yang akan dikembalikan
1 berarti akan banyak hasil yang hampir mirip atau banyak typo yang akan dikembalikan - minMatchCharLength
number
Menentukan jumlah karakter minimal dalam query agar pencarian terjadi.
Implementasi
Memanggil Data
import Fuse from "fuse.js";
import blogs from './blogs.js'
const fuse = new Fuse(blogs, {
keys: [],
includeScore: false,
threshold: 0,
minMatchCharLength: 3,
});
Menentukan Property
Selain keys untuk memberi tau Fuse property mana yang dijadikan keyword, di keys juga terdapat property weight yang digunakan untuk memberikan bobot pada setiap properti untuk menentukan seberapa penting properti tersebut dalam pencarian. Weight bisa diisi dari 0.1 sampai 1.
import Fuse from "fuse.js";
import blogs from './blogs.js'
const fuse = new Fuse(blogs, {
keys: [
{
name: 'title',
weight: 0.4,
},
{
name: 'descriptions',
weight: 0.2,
},
{
name: 'categories',
weight: 0.4
}
],
includeScore: false,
threshold: 0,
minMatchCharLength: 3,
});
Bobot yang paling tinggi berada di title
dan categories
.
Mengatur Threshold dan Minimal Char Length
Dengan mengatur threshold 0.2
akan menghasilkan kemiripan tinggi dengan kata kunci yang diberikan. Kalau 0.5 akan menghasilkan item yang kemungkinan besar jauh dari keyword yang diberikan.
import Fuse from "fuse.js";
import blogs from './blogs.js'
const fuse = new Fuse(blogs, {
keys: [
{
name: 'title',
weight: 0.4,
},
{
name: 'descriptions',
weight: 0.2,
},
{
name: 'categories',
weight: 0.4
}
],
includeScore: false,
threshold: 0.2,
minMatchCharLength: 3,
});
Membuat Fungsi Search
import Fuse from "fuse.js";
import blogs from './blogs.js'
const fuse = new Fuse(blogs, {
keys: [
{
name: 'title',
weight: 0.4,
},
{
name: 'descriptions',
weight: 0.2,
},
{
name: 'categories',
weight: 0.4
}
],
includeScore: false,
threshold: 0.2,
minMatchCharLength: 3,
});
const search = (query) => {
if (typeof query !== 'string' || query.length < 3) {
return 'Minimal 3 karakter';
}
const result = fuse.search(query).map((result) => result.item);
if (result.length === 0) {
return 'Keyword yang kamu cari tidak ada';
} else {
return result;
}
}
Percobaan Ke-1
Percobaan pertama mau nyari berdasarkan categories
.
console.log(search('Backend'));
Hasil:
[
{
"title": "Membangun API dengan Express.js",
"descriptions": "Langkah-langkah membuat API menggunakan Express.js.",
"categories": [ "Node.js", "Backend", "Express" ],
"created_at": "2024-03-04",
"updated_at": "2024-03-08"
},
{
"title": "Dasar-dasar Prisma ORM",
"descriptions": "Bagaimana menggunakan Prisma sebagai ORM di proyek Node.js.",
"categories": [ "Node.js", "Prisma", "Backend" ],
"created_at": "2024-03-05",
"updated_at": "2024-03-09"
}
]
Percobaan Ke-2
Mau mencari berdasarkan title
sengaja aku buat agak typo. Target “Membuat Animasi”.
console.log(search('buat anime'));
Hasil:
[
{
"title": "Membuat Animasi dengan Framer Motion",
"descriptions": "Panduan animasi sederhana dengan Framer Motion.",
"categories": [ "React", "Frontend", "Framer Motion" ],
"created_at": "2024-03-06",
"updated_at": "2024-03-10"
}
]
Percobaan Ke-3
Menggunakan keyword 3 huruf saja. Dengan target “Frontend”.
console.log(search('Fro'));
Hasil:
[
{
"title": "Belajar Next.js untuk Pemula",
"descriptions": "Panduan dasar untuk memulai dengan Next.js.",
"categories": [ "Next.js", "JavaScript", "Frontend" ],
"created_at": "2024-03-01",
"updated_at": "2024-03-05"
},
{
"title": "Mengenal Tailwind CSS",
"descriptions": "Cara menggunakan Tailwind CSS untuk styling yang cepat dan efisien.",
"categories": [ "Frontend", "CSS", "Tailwind" ],
"created_at": "2024-03-02",
"updated_at": "2024-03-06"
},
{
"title": "Membuat Animasi dengan Framer Motion",
"descriptions": "Panduan animasi sederhana dengan Framer Motion.",
"categories": [ "React", "Frontend", "Framer Motion" ],
"created_at": "2024-03-06",
"updated_at": "2024-03-10"
},
{
"title": "Menerapkan Autentikasi di Next.js",
"descriptions": "Menggunakan NextAuth untuk autentikasi di aplikasi Next.js.",
"categories": [ "Frontend", "Next.js", "Auth" ],
"created_at": "2024-03-07",
"updated_at": "2024-03-11"
},
{
"title": "Mengenal Cypress untuk Testing",
"descriptions": "Bagaimana menggunakan Cypress untuk pengujian otomatis.",
"categories": [ "Testing", "Cypress", "Frontend" ],
"created_at": "2024-03-08",
"updated_at": "2024-03-12"
}
]
Teman - teman bisa coba sendiri, atau mau coba langsung source code yang sudah ada @github/fuzzy-search-fusejs.
Mungkin itu saja yang bisa saya bagikan, semoga bisa menjadi solusi untuk project javascript kamu. Terimakasih sudah membaca 🙏😁.