Membuat Fitur Pencarian di Javascript Menggunakan Fuse.js

Fuse.js merupakan fuzzy searching library javascript yang bisa melakukan pencarian lebih dari 1 sumber (title, categories, descriptions, etc).

Daftar Isi
Membuat Fitur Pencarian di Javascript Menggunakan Fuse.js

fusejs.io | NPM

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.

  1. Bisa mengatur threshold atau tingkat toleransi
  2. Pencocokan multi kata, sehingga mampu mencari beberapa kata sekaligus
  3. Pencarian bebas typo, artinya pengguna tidak perlu menuliskan persis nama item yang ingin dituju
  4. 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 file blogs.js memiliki banyak property mulai dari title, descriptions, categories, created_at, updated_at. Kita bisa melakukan konfigurasi agar Fuse hanya mencari title, descriptions, categories saja.
  • includeScore boolean
    Property ini hanya bisa diisi dengan true atau false saja. Jika true 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,
});
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 🙏😁.

Type your title notification

Write to describe this notification