התוסף pg_textsearch ב-Cloud SQL ל-PostgreSQL מספק חיפוש טקסט מלא באמצעות אלגוריתם הניקוד BM25 (Best Matching 25), שהוא אלגוריתם סטנדרטי בתעשייה, כדי לספק ניקוד רלוונטיות מדויק מאוד. התוסף הוא פרויקט קוד פתוח שזמין ב-GitHub.
התוסף pg_textsearch דורש PostgreSQL מגרסה 17 ואילך.
מכיוון ש-pg_textsearch תומכת בתדירות מסמך הפוכה, ברוויית תדירות מונחים ובנורמליזציה של אורך המסמך, היא יכולה להפיק תוצאות רלוונטיות יותר מאשר הפונקציה המובנית ts_rank של PostgreSQL. בנוסף, מכיוון שהוא פועל ישירות בדפי אחסון רגילים של PostgreSQL, לא צריך להתקין מנוע חיצוני כמו Elasticsearch, או לדאוג לתחזוקה של שני אשכולות ולסנכרון נתונים. באמצעות pg_textsearch, אתם יכולים ליצור חוויות חיפוש חזקות, ניתנות להרחבה ורלוונטיות מאוד בלי לצאת מהסביבה של PostgreSQL.
דרכים שונות לחיפוש
יש כמה אפשרויות לחיפוש טקסט ב-Cloud SQL ל-PostgreSQL:
התאמה מדויקת: בחיפוש SQL סטנדרטי, משתמשים בהצהרות
LIKEו-ILIKEכדי לסרוק רצף מדויק של תווים. דוגמה לשאילתה:ILIKE '%smart fitness watches%'. השאילתה הזו תמצא מופעים כמו:- "כדאי לעיין במבצעים שלנו על שעוני כושר חכמים חדשים".
- "שעונים חכמים לאימוני כושר הם מתנות נהדרות".
עם זאת, היא לא תצליח למצוא:
- "Runners want a smart waterproof fitness watch."
- "This watch is particularly smart about fitness."
חיפוש טקסט מלא: חיפוש טקסט מלא משתמש באלגוריתם BM25 ובפונקציה
tsvectorכדי לחלק את הטקסט למילים בסיסיות, להתעלם ממילות סינון ולדרג את הרלוונטיות. היא מבינה את כללי השפה, כולל צורות רבים ודקדוק, ומתחשבת בתדירות המילים. חיפוש טקסט מלא שלsmart AND fitness AND watchesימצא את המקרים שהשאילתה לדוגמה עם ההתאמה המדויקת לא תמצא, וגם מקרים מורכבים יותר כמו אלה:- "שעון חכם מושלם לשגרת הכושר היומית שלך".
- "Not every watch is this smart when it comes to fitness."
עם זאת, היא לא תצליח למצוא:
- "שעון חכם שמודע לבריאות יכול לעזור לכם בתוכנית האימונים".
- "הצמיד החכם הזה למעקב אחר פעילות גופנית הוא מציאה".
חיפוש סמנטי: חיפוש סמנטי ממיר טקסט לווקטורים ומודד את מרחק הדמיון באמצעות מודלים של AI. הוא מבין משמעות, כוונה, הקשר, מילים נרדפות ומושגים קשורים. חיפוש סמנטי של
smart fitness watchesימצא את המקרים לדוגמה ששיטות החיפוש האחרות יפספסו. הוא יבין ש'שעון חכם עם מעקב אחר מדדי בריאות' זהה ל'שעון לאימוני כושר', וגם ש'צמיד חכם עם מעקב אחר פעילות גופנית' יכול להיות רלוונטי. יכול להיות שהיא תתאים בטעות לרצועת מד צעדים אם היא לא תיתן עדיפות מספקת למילה 'שעון'.
התקנת התוסף pg_textsearch
כדי להתקין ולהפעיל את pg_textsearch, פועלים לפי השלבים הבאים:
מגדירים את הדגל
cloudsql.enable_pg_textsearchלערךonכמו שמתואר במאמר הגדרת דגלים של מסד נתונים. הפעולה הזו תוסיף אתpg_textsearchלshared_preload_libraries.התקנת התוסף
pg_textsearchCREATE EXTENSION pg_textsearch;מאמתים את ההתקנה:
SELECT extversion FROM pg_extension WHERE extname = 'pg_textsearch'
חיפוש באמצעות pg_textsearch
נניח שמילאתם נתונים בטבלת הדוגמה הבאה:
CREATE TABLE documents (
doc_id TEXT PRIMARY KEY,
content TEXT,
text_embedding vector(3072)
GENERATED ALWAYS AS (embedding('gemini-embedding-001', content)) STORED
);
לפני שמשתמשים בחיפוש טקסט מלא, צריך ליצור קודם אינדקס BM25:
CREATE INDEX idx_docs_bm25
ON documents
USING bm25 (content)
WITH (text_config = 'english');
אחר כך אפשר להזין שאילתת חיפוש של טקסט מלא, כמו זו:
SELECT doc_id, content, content <@> 'database system'
AS score FROM documents
ORDER BY content <@> 'database system'
ASC LIMIT 5;
ביצוע חיפושים היברידיים באמצעות pg_textsearch ו-vector
אתם יכולים להשתמש ב-pg_textsearch יחד עם התוסף vector חיפוש סמנטי כדי לבצע חיפושים היברידיים. כך מתקינים את התוסף vector חיפוש סמנטי:
CREATE EXTENSION IF NOT EXISTS vector CASCADE;
מזינים שאילתת חיפוש היברידית סמנטית וטקסט מלא, כמו זו:
WITH
-- Semantic search results
vector_search AS (
SELECT doc_id,
RANK () OVER (ORDER BY text_embedding <=>
google_ml.embedding('gemini-embedding-001',
'database')::VECTOR ) AS rank
FROM documents
ORDER BY text_embedding <=> google_ml.embedding('gemini-embedding-001',
'database')::VECTOR
LIMIT 10
),
-- Full text search results
text_search AS (
SELECT doc_id,
RANK () OVER (ORDER BY content <@> 'database' ASC) AS rank
FROM documents
ORDER BY content <@> 'database' ASC
LIMIT 10
)
-- RRF combining both semantic and full text search results
SELECT
COALESCE(vector_search.doc_id, text_search.doc_id) AS id,
COALESCE(1.0 / (60 + vector_search.rank), 0.0) +
COALESCE(1.0 / (60 + text_search.rank), 0.0) AS rrf_score
FROM vector_search
FULL OUTER JOIN text_search ON vector_search.doc_id = text_search.doc_id
ORDER BY rrf_score DESC
LIMIT 5;
דגלים להגדרת התוסף pg_textsearch
כדי להגדיר חיפוש טקסט מלא של pg_textsearch, משתמשים בדגלים הבאים:
-
pg_textsearch.bulk_load_threshold: תנאים לכל טרנזקציה לפני מעבר אוטומטי. כדי להשבית, צריך להגדיר את הערך כ-0. ברירת מחדל: 100,000. -
pg_textsearch.compress_segments: דחיסת בלוקים של פוסטים בפלחים חדשים. ברירת מחדל:on. -
pg_textsearch.default_limit: המספר המקסימלי של מסמכים שקיבלו ניקוד כשלא מופיעה פסוקיתLIMIT. ברירת מחדל: 1,000. -
pg_textsearch.memtable_pages_threshold: מספר הדפים לשרשור לפני מעבר אוטומטי לדף הבא. כדי להשבית, צריך להגדיר את הערך כ-0. ברירת מחדל: 64. -
pg_textsearch.segments_per_level: מספר הפלחים בכל רמה לפני שהדחיסה האוטומטית מתבצעת. הטווח: 2-64. ברירת מחדל: 8.