Full Text Search di PostgreSQL
Pendahuluan
Full Text Search (FTS) adalah fitur canggih dalam basis data yang memungkinkan pencarian teks secara efisien dan akurat. PostgreSQL, salah satu sistem manajemen basis data relasional terkemuka, menawarkan dukungan kuat untuk FTS. Dalam artikel ini kita akan membahas konsep dasar FTS di PostgreSQL, seperti tsvector, tsquery, dan indeks seperti GIN. Selain itu, kita akan melihat bagaimana menggunakannya dalam aplikasi Golang dengan GORM, lengkap dengan contoh nyata dan simulasi.
Apa itu Full Text Search?
Full Text Search adalah metode untuk mencari teks dalam dokumen atau kolom teks dengan cara yang lebih pintar dibandingkan pencarian string biasa (misalnya, menggunakan LIKE). FTS memecah teks menjadi kata-kata individual (token), mengabaikan kata-kata umum (stop words), dan mendukung pencarian berdasarkan relevansi. Fitur ini sangat berguna untuk aplikasi seperti mesin pencari, sistem manajemen konten, atau katalog produk.
Konsep Dasar Full Text Search di PostgreSQL
1. tsvector
tsvector adalah tipe data khusus di PostgreSQL yang merepresentasikan teks dalam format yang dioptimalkan untuk pencarian teks. Teks dipecah menjadi token (kata-kata), stop words dihilangkan, dan setiap token disimpan bersama posisinya dalam teks asli.
Contoh:
Misalkan kita memiliki teks: "PostgreSQL adalah basis data yang hebat."
Jika diubah menjadi tsvector:
'postgresql':1 'basis':2 'data':3 'hebat':4
Cara Kerja:
Kata "adalah" dan "yang" dihilangkan karena dianggap stop words (tergantung bahasa).
Setiap token diberi nomor posisi untuk mendukung pencarian berdasarkan kedekatan kata.
2. tsquery
tsquery adalah tipe data untuk merepresentasikan query pencarian teks penuh. Anda dapat menentukan kata atau frasa yang dicari, serta menggunakan operator logika seperti & (AND), | (OR), dan ! (NOT).
Contoh:
Untuk mencari dokumen yang mengandung "PostgreSQL" dan "hebat":
'postgresql' & 'hebat'
3. Fungsi to_tsvector dan to_tsquery
to_tsvector: Mengubah teks menjadi tsvector.
to_tsquery: Mengubah string query menjadi tsquery.
Contoh:
SELECT to_tsvector('PostgreSQL adalah basis data yang hebat');
Output:
'postgresql':1 'basis':2 'data':3 'hebat':4
SELECT to_tsquery('postgresql & hebat');
Output:
'postgresql' & 'hebat'
4. Operator Pencarian @@
Operator @@ digunakan untuk mencocokkan tsvector dengan tsquery.
Contoh:
SELECT to_tsvector('PostgreSQL adalah basis data yang hebat') @@ to_tsquery('postgresql & hebat');
Output:
t
Artinya, teks tersebut cocok dengan query.
Indeks untuk Full Text Search
Pencarian teks penuh bisa lambat pada dataset besar tanpa indeks. PostgreSQL mendukung dua jenis indeks utama untuk FTS: GIN dan GiST.
1. GIN (Generalized Inverted Index)
GIN adalah indeks yang sangat efisien untuk FTS. Ini menyimpan mapping dari setiap token ke dokumen yang mengandungnya, memungkinkan pencarian cepat bahkan untuk query kompleks.
Contoh Pembuatan Indeks GIN:
CREATE INDEX idx_gin ON documents USING GIN (to_tsvector('indonesian', content));
2. GiST (Generalized Search Tree)
GiST adalah alternatif lain yang lebih fleksibel, tetapi kurang efisien dibandingkan GIN untuk kebanyakan kasus. Cocok untuk pencarian dengan kedekatan kata.
Contoh Pembuatan Indeks GiST:
CREATE INDEX idx_gist ON documents USING GiST (to_tsvector('indonesian', content));
Studi kasus Database Buku
Mari kita buat contoh nyata dengan database buku. Kita akan membuat tabel books dan melakukan pencarian teks penuh berdasarkan judul dan deskripsi.
1. Membuat Tabel
CREATE TABLE books (
id SERIAL PRIMARY KEY,
title TEXT,
description TEXT
);
2. Mengisi Data
INSERT INTO books (title, description) VALUES
('Belajar PostgreSQL', 'Buku ini mengajarkan dasar-dasar PostgreSQL untuk pemula.'),
('PostgreSQL Lanjutan', 'Panduan mendalam tentang fitur canggih PostgreSQL.'),
('Golang dan PostgreSQL', 'Cara menggunakan Golang dengan PostgreSQL.');
3. Membuat Indeks GIN
Kita akan mengindeks kombinasi title dan description:
CREATE INDEX idx_books_fts ON books USING GIN (
to_tsvector('indonesian', title || ' ' || description)
);
4. Melakukan Pencarian
Misalkan kita ingin mencari buku yang mengandung "PostgreSQL" dan "pemula":
SELECT * FROM books
WHERE to_tsvector('indonesian', title || ' ' || description) @@ to_tsquery('indonesian', 'postgresql & pemula');
Hasil:
Mengembalikan buku dengan judul "Belajar PostgreSQL".
Implementasi di Golang dengan GORM
Sekarang, kita akan mengimplementasikan pencarian ini dalam Golang menggunakan GORM.
1. Menghubungkan ke Database
package main
import (
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
func main() {
dsn := "host=localhost user=postgres password=secret dbname=mydb port=5432 sslmode=disable"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic("gagal terhubung ke database")
}
// Gunakan db di sini
}
2. Membuat Model
type Book struct {
ID uint `gorm:"primaryKey"`
Title string
Description string
}
3. Melakukan Pencarian Teks Penuh
Kita akan menggunakan query SQL mentah dengan GORM:
var books []Book
query := "postgresql & pemula"
err := db.Raw("SELECT * FROM books WHERE to_tsvector('indonesian', title || ' ' || description) @@ to_tsquery('indonesian', ?)", query).Scan(&books).Error
if err != nil {
panic("gagal melakukan pencarian")
}
for _, book := range books {
println(book.Title, "-", book.Description)
}
Hasil:
Menampilkan buku yang cocok dengan query.
Simulasi Cara Kerja
Mari kita simulasikan bagaimana FTS bekerja:
Data:
Buku 1: "Belajar PostgreSQL" - "Buku ini mengajarkan dasar-dasar PostgreSQL untuk pemula."
Buku 2: "PostgreSQL Lanjutan" - "Panduan mendalam tentang fitur canggih PostgreSQL."
Buku 3: "Golang dan PostgreSQL" - "Cara menggunakan Golang dengan PostgreSQL."
tsvector untuk Buku 1:
'belajar':1 'postgresql':2,8 'buku':3 'mengajarkan':4 'dasar':5 'pemula':6
tsquery:
'postgresql' & 'pemula'
Pencocokan:
Buku 1: Mengandung "postgresql" dan "pemula" → Cocok.
Buku 2: Hanya "postgresql" → Tidak Cocok.
Buku 3: Hanya "postgresql" → Tidak Cocok.
Hasil: Hanya Buku 1 yang dikembalikan.
Tips Tambahan
Bahasa: Gunakan konfigurasi bahasa yang sesuai (misalnya, 'indonesian') agar tokenisasi dan stop words akurat.
Kinerja: Selalu gunakan indeks GIN untuk dataset besar.
Relevansi: Gunakan ts_rank untuk mengurutkan hasil berdasarkan relevansi.
Pemeliharaan: Perbarui indeks saat data berubah dengan CREATE INDEX ulang jika perlu.
Kesimpulan
Full Text Search di PostgreSQL adalah solusi powerful untuk pencarian teks yang efisien. Dengan tsvector, tsquery, dan indeks seperti GIN, Anda dapat membangun sistem pencarian yang cepat dan akurat. Integrasi dengan Golang dan GORM memungkinkan Anda menggunakannya dalam aplikasi modern dengan mudah. Semoga artikel ini membantu Anda memahami dan mengimplementasikan FTS dengan baik!
Last updated