Skip to content

Cara Mudah Implementasi Hybrid Search di PostgreSQL Panduan Lengkap untuk yang Berani Ngulik

Published: at 09.30

Udah pernah denger tentang hybrid search di PostgreSQL? Kalo belum, tenang aja. Artikel ini bakal ngasih tau antum semua yang perlu antum tau buat bikin fitur pencarian di aplikasi antum jadi makin keren. Kita bakal bahas gimana cara ngombinasiin full-text search (FTS) yang udah ada di PostgreSQL sama vector search yang baru-baru kedenger pas jaman Eai ini. Siap-siap aja, skillset antum bakal naik level abis baca ini!

Apa Sih Hybrid Search di PostgreSQL Itu?

Hybrid search di PostgreSQL itu kayak antum punya dua superpowers sekaligus buat nyari data:

  1. Full-Text Search (FTS): Jagoan buat nyari kata-kata spesifik.
  2. Vector Search: Ahlinya buat nangkep makna dan konteks.

Nah, hybrid search ini ngegabungin kedua kekuatan itu. Jadi, hasil pencariannya bisa lebih akurat dan smart. Keren kan?

  1. Hasil Pencarian Lebih Relevan: Kombinasi FTS dan vector search bikin hasil pencarian antum jadi lebih pas dan sesuai sama apa yang user cari.
  2. Fleksibel: Bisa di-adjust sesuai kebutuhan aplikasi lo.
  3. Performa Oke: Dengan setting yang bener, hybrid search bisa jalan cepet bahkan buat database gede.
  4. Hemat Resources: Nggak perlu pake tools tambahan, cukup pake fitur yang udah ada di PostgreSQL.

Belajar Jargon Dulu Sensei

Biar antum gak bingung, nih gue jelasin beberapa istilah teknis yang bakal sering muncul pas antum implementasi hybrid search:

1. Full-Text Search (FTS)

Apaan sih?: Metode pencarian yang bisa nyari kata atau frasa di dalam teks panjang.

Buat apa?: Biar user bisa nyari konten berdasarkan kata kunci, mirip kayak search engine.

Contoh: antum bisa nyari “resep kopi” dan nemu artikel yang ada kata “kopi” di dalemnya, meskipun judulnya bukan “resep kopi”.

Apaan sih?: Metode pencarian yang ngubah teks jadi angka-angka (vector), terus nyari yang paling mirip.

Buat apa?: Biar bisa nemu konten yang “maksudnya” mirip, meskipun kata-katanya beda.

Contoh: antum nyari “mobil sport”, tapi ketemu juga artikel tentang “kendaraan balap” karena maknanya mirip.

3. pgvector

Apaan sih?: Extension PostgreSQL buat bikin dan nyimpen vector, plus nyari kesamaan antar vector.

Buat apa?: Biar PostgreSQL bisa handling vector search.

Gimana makenya?: Install extensionnya, terus antum bisa bikin kolom tipe “vector” di tabel lo.

4. Embedding

Apaan sih?: Proses ngubah kata atau kalimat jadi vector angka.

Buat apa?: Biar komputer bisa “ngerti” makna teks dan nyari yang mirip-mirip.

Contoh: Kalimat “Kucing makan ikan” jadi vector [0.2, -0.5, 0.1, …].

5. Cosine Similarity

Apaan sih?: Cara ngitung seberapa mirip dua vector.

Buat apa?: Nentuin seberapa relevan hasil pencarian vector.

Gimana kerjanya?: Makin deket ke 1, makin mirip. Makin deket ke 0, makin beda.

6. GIN Index

Apaan sih?: Generalized Inverted Index, tipe index di PostgreSQL yang cocok buat FTS.

Buat apa?: Bikin pencarian full-text jadi lebih cepet.

Gimana makenya?:

CREATE INDEX idx_fts ON articles USING GIN (to_tsvector('english', content));

7. HNSW Index

Apaan sih?: Hierarchical Navigable Small World, algoritma buat bikin index vector yang cepet.

Buat apa?: Bikin vector search jadi lebih ngebut, terutama buat dataset gede.

Gimana makenya?:

CREATE INDEX idx_vector ON articles USING hnsw (content_vector vector_cosine_ops);

8. tsvector dan tsquery

Apaan sih?: Tipe data khusus di PostgreSQL buat full-text search.

Buat apa?:

Contoh:

SELECT to_tsvector('english', 'The quick brown fox') @@ to_tsquery('english', 'quick & fox');

9. EXPLAIN ANALYZE

Apaan sih?: Perintah PostgreSQL buat liat gimana query antum dieksekusi.

Buat apa?: Ngebantu antum ngerti performa query dan nemuin bottleneck.

Gimana makenya?:

EXPLAIN ANALYZE SELECT * FROM articles WHERE ...;

Lanjut ke Teknis

Cara Implementasi Hybrid Search di PostgreSQL

1. Setting Up

Pertama-tama, pastiin PostgreSQL antum udah support pgvector. Kalo belum, install dulu:

CREATE EXTENSION IF NOT EXISTS pgvector;

2. Bikin Tabel dan Index

CREATE TABLE articles (
    id SERIAL PRIMARY KEY,
    title TEXT,
    content TEXT,
    content_vector vector(384)  -- Sesuaiin dimensi vector sama model embedding yang antum pake
);

-- Index buat FTS
CREATE INDEX idx_fts ON articles USING GIN (to_tsvector('english', title || ' ' || content));

-- Index buat Vector Search
CREATE INDEX idx_vector ON articles USING ivfflat (content_vector vector_cosine_ops);

3. Insert Data

INSERT INTO articles (title, content, content_vector)
VALUES ('Cara Bikin Kopi Enak', 'Artikel tentang cara bikin kopi yang enak...', '[0.1, 0.2, ..., 0.3]'::vector);
SELECT id, title,
       ts_rank(to_tsvector('english', title || ' ' || content), to_tsquery('coffee')) AS text_rank,
       1 - (content_vector <=> '[0.1, 0.2, ..., 0.3]'::vector) AS vector_similarity
FROM articles
WHERE to_tsvector('english', title || ' ' || content) @@ to_tsquery('coffee')
ORDER BY (text_rank * 0.7 + vector_similarity * 0.3) DESC
LIMIT 10;
-- Function untuk menggabungkan multiple vector embeddings
CREATE OR REPLACE FUNCTION combine_vectors(VARIADIC vectors vector[])
RETURNS vector AS $$
DECLARE
  combined_vector vector;
BEGIN
  combined_vector := vectors[1];
  FOR i IN 2..CARDINALITY(vectors) LOOP
    combined_vector := combined_vector + vectors[i];
  END LOOP;
  RETURN combined_vector / CARDINALITY(vectors); -- Rata-rata vector
END;
$$ LANGUAGE plpgsql;

-- Query untuk multiple keyword search dengan vector search
SELECT id, name, description
FROM products
WHERE to_tsvector('english', name || ' ' || description) @@ to_tsquery('kemeja & pria & panjang')
   OR 1 - (product_vector <=> combine_vectors(
       embedding('kemeja'),  -- Asumsi ada function embedding() untuk menghasilkan vector
       embedding('pria'),
       embedding('panjang')
   )) > 0.8  -- Threshold similarity
ORDER BY (
    ts_rank(to_tsvector('english', name || ' ' || description), to_tsquery('kemeja & pria & panjang')) * 0.6 +
    (1 - (product_vector <=> combine_vectors(embedding('kemeja'), embedding('pria'), embedding('panjang')))) * 0.4
) DESC
LIMIT 20;

Penjelasan:

  1. combine_vectors function: Fungsi ini menerima sejumlah vector sebagai input dan menghasilkan rata-rata dari vector-vector tersebut. Ini digunakan untuk menggabungkan vector embeddings dari multiple keywords. Query: Query ini menggabungkan full-text search dan vector search. combine_vectors digunakan untuk menghitung similarity antara product vector dan gabungan vector embeddings dari keyword “kemeja”, “pria”, dan “panjang”.

1. Weighting yang Pas

Coba-coba adjust bobot antara FTS dan vector search. Misalnya:

ORDER BY (text_rank * 0.7 + vector_similarity * 0.3) DESC

Di sini, FTS dikasih bobot 70% dan vector search 30%. Sesuaiin aja sama kebutuhan lo.

2. Indexing yang Bener

Index yang tepat bisa bikin query antum jadi ngebut. Pake GIN index buat FTS dan HNSW index dari pgvector:

CREATE INDEX idx_fts ON articles USING GIN (to_tsvector('english', title || ' ' || content));
CREATE INDEX idx_vector ON articles USING hnsw (content_vector vector_cosine_ops);

3. Query Optimization

Pake EXPLAIN ANALYZE buat liat performa query lo:

EXPLAIN ANALYZE SELECT ... -- Query hybrid search antum di sini

Dari sini, antum bisa liat bagian mana yang perlu dioptimasi.

Studi Kasus: Implementasi Hybrid Search di Aplikasi E-commerce

Bayangin antum lagi bikin fitur pencarian buat toko online. User bisa nyari produk pake keyword, tapi kadang mereka juga pengen nyari produk yang “mirip-mirip”.

SELECT id, name, description,
       ts_rank(to_tsvector('english', name || ' ' || description), to_tsquery('smartphone')) AS text_rank,
       1 - (product_vector <=> query_vector) AS similarity
FROM products
WHERE to_tsvector('english', name || ' ' || description) @@ to_tsquery('smartphone')
   OR 1 - (product_vector <=> query_vector) > 0.8
ORDER BY (text_rank * 0.6 + similarity * 0.4) DESC
LIMIT 20;

Query di atas bakal nyari produk yang cocok sama keyword “smartphone”, tapi juga nampilin produk yang vector-nya mirip sama query vector (misalnya vector dari gambar atau deskripsi produk yang dicari user sebelumnya).

Kesimpulan: Hybrid Search, Cara Keren Buat Upgrade Fitur Pencarian Lo

Hybrid search di PostgreSQL buka banyak kemungkinan buat bikin fitur pencarian yang lebih canggih. Dengan gabungin FTS dan vector search, antum bisa kasih user pengalaman nyari yang lebih akurat dan relevan.

Inget, implementasi hybrid search ini perlu dioptimasi terus. Jangan ragu buat eksperimen dengan berbagai setting dan selalu monitor performanya. Dengan waktu dan usaha, antum bakal nemu sweet spot yang bikin aplikasi antum makin yahud!

Gimana? Udah siap implementasiin hybrid search di proyek antum berikutnya? Kalo ada pertanyaan atau mau sharing pengalaman, jangan ragu buat komen di bawah ya! Happy gulik, guys!

janlup tetep pamer di #PAMERAJADULU alias ngulik aja dulu