אינדקסים של RUM ב-AlloyDB ל-PostgreSQL מאפשרים להאיץ שאילתות חיפוש טקסט מלא על ידי אחסון מידע על מיקום ומאפיינים לצד לקסמות באינדקס.
אפשר להפעיל את התוסף rum כדי ליצור אינדקסים של RUM ולשפר את דירוג הרלוונטיות, את החיפושים של ביטויים ואת המיון לפי חותמות זמן.
לפני שמתחילים
כדי ליצור את התוסף RUM, צריך להיות לכם תפקיד מסד הנתונים alloydbsuperuser.
תפקיד האדמין ב-AlloyDB (roles/alloydb.admin) ב-IAM נותן שליטה מלאה במשאבים של AlloyDB, אבל לא נותן את תפקיד מסד הנתונים alloydbsuperuser. כדי ליצור את התוסף, אדמין צריך להקצות לכם באופן מפורש את התפקיד alloydbsuperuser במסד הנתונים.
מידע נוסף על הענקת תפקידים זמין במאמר הוספת חשבון משתמש או חשבון שירות ב-IAM לאשכול.
יצירת תוסף RUM
צריך ליצור את התוסף RUM פעם אחת לכל מסד נתונים.
- מתחברים למסד הנתונים של AlloyDB באמצעות
psqlאו לקוח אחר. מידע נוסף זמין במאמר בנושא חיבור למופע של אשכול. מריצים את פקודת ה-SQL הבאה כדי ליצור את התוסף:
CREATE EXTENSION IF NOT EXISTS rum;
יצירת אינדקס RUM
כדי לבצע אופטימיזציה של שאילתות חיפוש טקסט מלא, צריך ליצור אינדקס RUM על הנתונים. ב-RUM יש כמה סוגי אופרטורים לתרחישי שימוש שונים.
סוגי מחלקות של מפעילי RUM
בטבלה הבאה מפורטים הסוגים השונים של מפעילי RUM ותרחישי השימוש העיקריים שלהם.
| סוג המפעיל | תרחיש השימוש העיקרי | מגבלות |
|---|---|---|
rum_tsvector_ops |
חיפוש טקסט מלא רגיל עם דירוג וחיפוש ביטויים. | לא רלוונטי |
rum_tsvector_hash_ops |
אינדקס קטן יותר ועדכונים מהירים יותר לחיפוש טקסט מלא. | לא תומך בחיפוש קידומות. |
rum_tsvector_addon_ops |
חיפוש טקסט מלא ממוין לפי עמודה אחרת. | לא רלוונטי |
rum_anyarray_ops |
חיפוש בתוך עמודות של מערכים. | לא רלוונטי |
rum_<TYPE>_ops |
הוספה לאינדקס של סוגים סקלריים לשאילתות שמבוססות על מרחק. | לא רלוונטי |
rum_tsvector_hash_addon_ops |
חיפוש טקסט מלא מבוסס-גיבוב שממוין לפי עמודה אחרת. | לא תומך בהתאמה של קידומת. |
rum_tsquery_ops |
יצירת אינדקס של ערכי tsquery מאוחסנים לחיפוש הפוך. |
לא רלוונטי |
rum_anyarray_addon_ops |
חיפוש במערך שממוין לפי עמודה אחרת. | לא רלוונטי |
אינדקס לחיפוש טקסט מלא בסיסי
משתמשים במחלקה rum_tsvector_ops של אופרטורים לחיפוש טקסט רגיל שדורש דירוג מהיר ויכולות חיפוש של צירופי מילים. במחלקת האופרטורים הזו מאוחסן המיקום של כל לקסמה באינדקס. בדוגמה הבאה נוצרת טבלה בשם documents עם עמודה מסוג content.
צור טבלה בשם
documents:CREATE TABLE documents ( id SERIAL PRIMARY KEY, title TEXT NOT NULL, content TEXT NOT NULL, published_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() );מאכלסים את הטבלה
documentsבנתונים לדוגמה:INSERT INTO documents (title, content) VALUES ('Title', 'This search engine is working as intended');הוספת עמודת
tsvectorשנוצרה לטבלה. בעמודה הזו נשמר באופן אוטומטי הטקסט שעבר עיבוד, והיא משפרת את ביצועי השאילתות:ALTER TABLE documents ADD COLUMN search_vector tsvector GENERATED ALWAYS AS (to_tsvector('english', content)) STORED;יוצרים את אינדקס ה-RUM בעמודה החדשה
search_vector:CREATE INDEX idx_docs_rum ON documents USING rum (search_vector rum_tsvector_ops);שולחים שאילתה לטבלה באמצעות האינדקס. האופרטור
<=>מחשב את ציון הרלוונטיות או המרחק בין המסמך לבין השאילתה ישירות מהאינדקס, וכך מאפשר מיון מהיר:SELECT title, content FROM documents WHERE search_vector @@ to_tsquery('english', 'search <-> engine') ORDER BY search_vector <=> to_tsquery('english', 'search <-> engine');מילוי טבלת
documentsבנתונים נוספים:INSERT INTO documents (title, content) VALUES ('Title1', 'English is my primary language.'); INSERT INTO documents (title, content) VALUES ('Title2', 'Google has a great engineering culture');מריצים שאילתת חיפוש של קידומת. החיפוש הזה מוצא מסמכים שמכילים מילים שמתחילות ב-
eng, כמוengineerאוenglish:SELECT title, content FROM documents WHERE search_vector @@ to_tsquery('english', 'eng:*');
אינדקס לחיפוש אופטימלי של גיבוב
כדי להקטין את גודל האינדקס ולשפר את מהירות העדכון, משתמשים במחלקת האופרטור rum_tsvector_hash_ops. המחלקה הזו מאחסנת גיבוב (hash) של כל לקסמה במקום את הלקסמה המלאה. הגישה הזו יוצרת אינדקס קטן יותר, אבל לא תומכת בחיפוש לפי תחילית. בדוגמה הבאה נניח שיש לכם טבלה בשם documents עם עמודה בשם search_vector.
יוצרים את אינדקס ה-RUM באמצעות מחלקת האופרטור hash:
CREATE INDEX idx_docs_rum_hash ON documents USING rum (search_vector rum_tsvector_hash_ops);מילוי טבלת
documentsבנתונים נוספים:INSERT INTO documents (title, content) VALUES ('Title3', 'That person was driving incredibly fast, however the routing was not very efficient');מריצים שאילתת התאמה רגילה:
SELECT * FROM documents WHERE search_vector @@ to_tsquery('english', 'fast & efficient');
אינדקס לחיפוש ממוין לפי חותמת זמן
משתמשים במחלקת האופרטורים rum_tsvector_addon_ops כדי לבצע אופטימיזציה של שאילתות שמסננות לפי טקסט וממיינות לפי שדה אחר, כמו חותמת זמן. התבנית הזו מאחסנת את הערך של השדה הנוסף ישירות באינדקס, וכך נמנעת פעולת מיון איטית אחרי החיפוש. בדוגמה הבאה אנחנו מניחים שיש לכם טבלה בשם documents עם עמודה search_vector ועמודה published_at.
יוצרים אינדקס שכולל את חותמת הזמן של
published_at:CREATE INDEX idx_docs_rum_timestamp ON documents USING rum (search_vector rum_tsvector_addon_ops, published_at) WITH (attach = 'published_at', to = 'search_vector');מריצים שאילתה שמחפשת מסמכים שמכילים את המילה
engineוממיינים אותם לפי תאריך הוצאה לאור. האינדקס מטפל ביעילות גם בחיפוש וגם במיון:SELECT title, published_at FROM documents WHERE search_vector @@ to_tsquery('english', 'engine') ORDER BY published_at DESC;
אינדקס לחיפוש במערך
אפשר להשתמש במחלקת האופרטורים rum_anyarray_ops כדי ליצור אינדקס לעמודות של מערכים, כמו רשימה של תגים. כך אפשר לבצע שאילתות יעילות לגבי מערכים שחופפים (&&), מכילים (@>) או מוכלים (<@) במערכים אחרים. בדוגמה הבאה מוסיפים עמודה מסוג tags לטבלה documents.
מוסיפים עמודה של
tagsוממלאים אותה בנתונים:ALTER TABLE documents ADD COLUMN tags TEXT[]; INSERT INTO documents (title, content, tags) VALUES ( 'Title4', 'Sample Text', ARRAY['ai', 'ml'] );יוצרים את אינדקס ה-RUM בעמודה
TEXT[]בשםtags:CREATE INDEX idx_tags_rum ON documents USING rum (tags rum_anyarray_ops);מריצים שאילתה כדי למצוא מסמכים שכוללים את התגים
aiאוml:SELECT * FROM documents WHERE tags && '{"ai", "ml"}';
אינדקס לסוגים סקלריים
משתמשים במחלקות האופרטורים rum_<TYPE>_ops כדי ליצור אינדקס לעמודות שמכילות ערכים רציפים, כמו מספרים שלמים, חותמות זמן או מספרים בנקודה צפה. מחלקות האופרטורים האלה מאפשרות להשתמש באופרטור <=> כדי לחשב ביעילות את המרחק בין הערכים. בדוגמה הבאה אנחנו מניחים שיש לכם טבלה בשם documents.
מוסיפים עמודה של מספר שלם כללי, כמו
rating, לטבלהdocuments:ALTER TABLE documents ADD COLUMN rating INT; UPDATE documents SET rating = floor(random() * 5 + 1);יוצרים אינדקס RUM בעמודה
rating:CREATE INDEX idx_rating_rum ON documents USING rum (rating rum_int4_ops);מריצים שאילתה כדי למצוא מסמכים עם
ratingשהכי קרוב לערך 5:SELECT title, rating FROM documents ORDER BY rating <=> 5;
אינדקס לחיפוש אופטימלי של גיבובים, ממוין לפי חותמת זמן
משתמשים במחלקת האופרטור rum_tsvector_hash_addon_ops כדי לשלב את היתרונות של אינדקס גיבוב עם יכולות המיון של אינדקס תוסף. במחלקת הנתונים הזו מאוחסן גיבוב של כל לקסמה, יחד עם הערך של עמודה נוספת. ההגדרה הזו תומכת במיון יעיל לפי העמודה הנוספת, אבל לא תומכת בהתאמה לתחילית. בדוגמה הבאה נניח שיש לכם טבלה בשם documents עם עמודה search_vector ועמודה של חותמות זמן published_at.
יוצרים אינדקס RUM שמשתמש במחלקת האופרטור hash וכולל את חותמת הזמן של
published_at:CREATE INDEX idx_docs_rum_hash_timestamp ON documents USING rum (search_vector rum_tsvector_hash_addon_ops, published_at) WITH (attach = 'published_at', to = 'search_vector');להריץ שאילתה שמוצאת מסמכים שמכילים את
engineוממיינת אותם לפי תאריך הוצאה לאור:SELECT title, published_at FROM documents WHERE search_vector @@ to_tsquery('english', 'engine') ORDER BY published_at DESC;
אינדקס לשאילתות מאוחסנות
משתמשים במחלקת האופרטורים rum_tsquery_ops כדי להוסיף לאינדקס ערכי tsquery. כך אפשר לבצע "חיפוש הפוך" ולזהות אילו שאילתות שמורות תואמות למסמך קלט נתון. בדוגמה הבאה נוצרת טבלה בשם queries.
יוצרים טבלה לאחסון שאילתות:
CREATE TABLE queries ( query_text tsquery ); INSERT INTO queries (query_text) VALUES (plainto_tsquery('AlloyDB is fast!'));יצירת אינדקס RUM בעמודה
query_text:CREATE INDEX idx_queries_rum ON queries USING rum (query_text rum_tsquery_ops);מריצים שאילתה כדי למצוא שאילתות מאוחסנות שתואמות למסמך:
SELECT * FROM queries WHERE to_tsvector('english', 'AlloyDB is fast') @@ query_text;
אינדקס לחיפוש במערך, ממוין לפי חותמת זמן
משתמשים במחלקת האופרטורים rum_anyarray_addon_ops כדי להוסיף לאינדקס עמודות של מערכים, יחד עם עמודה נוספת למיון. בדוגמה הבאה מניחים שיש לכם טבלה בשם documents עם עמודה tags ועמודת חותמת זמן published_at.
יוצרים אינדקס RUM בעמודה
tagsשכולל את חותמת הזמןpublished_at:CREATE INDEX idx_tags_rum_timestamp ON documents USING rum (tags rum_anyarray_addon_ops, published_at) WITH (attach = 'published_at', to = 'tags');מריצים שאילתה כדי למצוא מסמכים עם התג
ai, ממוינים לפי תאריך הוצאה לאור:SELECT title, published_at FROM documents WHERE tags @> '{"ai"}' ORDER BY published_at DESC;