Pernah membuat fitur pencarian di aplikasi tetapi hasilnya terlalu kaku? Jika pengguna salah mengetik sedikit saja (misalnya mencari "Prisma" tetapi diketik "Prisra"), database biasanya tidak akan menampilkan hasil apa pun.
Bagi pengguna PostgreSQL, masalah pencarian teks yang toleran terhadap typo (fuzzy search atau autocomplete) dapat diselesaikan dengan memanfaatkan ekstensi bawaan bernama pg_trgm (Trigram).
Panduan ini membahas cara mengintegrasikan dan menggunakan pg_trgm bersama Prisma ORM.
Ekstensi pg_trgm memecah teks menjadi potongan-potongan tiga karakter (trigram) untuk menghitung tingkat kemiripan antara dua string.
Sebagai contoh, kata "prisma" dipecah menjadi beberapa bagian trigram. Jika ada kata yang mirip diketikkan oleh pengguna, PostgreSQL dapat menghitung skor kemiripannya (dari skala 0 hingga 1) tanpa harus bergantung pada pencocokan string persis (exact match).
Cara paling bersih dalam ekosistem Prisma untuk mengaktifkan ekstensi PostgreSQL adalah melalui blok konfigurasi datasource dengan mengaktifkan fitur preview postgresqlExtensions.
Buka file schema.prisma Anda, lalu tambahkan konfigurasi berikut:
generator client {
provider = "prisma-client-js"
previewFeatures = ["postgresqlExtensions"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
extensions = [pg_trgm]
}
Dengan konfigurasi di atas, ketika Anda menjalankan perintah migrasi, Prisma akan otomatis mengeksekusi perintah SQL untuk mengaktifkan ekstensi pg_trgm di dalam database PostgreSQL Anda.
Pencarian berbasis kemiripan teks pada tabel berskala besar memerlukan indeks khusus agar performanya tetap cepat. Gunakan tipe indeks GIN (Generalized Inverted Index) dengan operator gin_trgm_ops.
Contoh implementasi pada model Article:
model Article {
id Int @id @default(autoincrement())
title String
content String
@@index([title(ops: raw("gin_trgm_ops"))], map: "articles_title_trgm_idx", type: Gin)
@@map("articles")
}
Setelah memperbarui schema.prisma, jalankan perintah migrasi seperti biasa di terminal:
npx prisma migrate dev --name init_pg_trgm
Prisma tidak menyediakan fungsi bawaan khusus untuk operator trigram pada API standar Prisma Client (findMany). Oleh karena itu, pencarian dilakukan menggunakan fungsi prisma.$queryRaw.
Berikut adalah contoh implementasi fungsi pencarian di backend:
Contoh kode untuk mencari artikel yang judulnya mirip dengan kata kunci pencarian dari pengguna, diurutkan dari yang paling akurat:
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function searchArticles(keyword) {
// Menggunakan fungsi similarity() dari pg_trgm
const results = await prisma.$queryRaw`
SELECT * FROM articles
WHERE similarity(title, ${keyword}) > 0.3
ORDER BY similarity(title, ${keyword}) DESC;
`;
return results;
}
Penjelasan: Angka > 0.3 adalah batasan minimum skor kemiripan. Semakin mendekati 1.0, hasil pencarian akan semakin spesifik dan ketat.
Operator % dapat digunakan untuk mencocokkan kemiripan berdasarkan aturan default dari ekstensi pg_trgm:
async function fuzzySearch(keyword) {
const results = await prisma.$queryRaw`
SELECT * FROM articles
WHERE title % ${keyword};
`;
return results;
}
Bagi proyek dengan versi Prisma yang tidak menggunakan fitur preview postgresqlExtensions, ekstensi dapat diaktifkan secara manual melalui file migrasi SQL:
npx prisma migrate dev --create-only --name manual_pg_trgm
migration.sql:
CREATE EXTENSION IF NOT EXISTS pg_trgm;
npx prisma migrate dev
Menggabungkan Prisma ORM dengan ekstensi pg_trgm PostgreSQL memungkinkan pembuatan fitur fuzzy search atau pencarian tahan typo dengan mudah tanpa harus memasang layanan mesin pencari eksternal yang kompleks.