PostgreSQL 適用的 AlloyDB 中的 RUM 索引可將位置和屬性資訊與索引中的詞素一併儲存,藉此加快全文搜尋查詢速度。您可以啟用 rum 擴充功能,建立 RUM 索引並最佳化關聯性排名、詞組搜尋和以時間戳記為準的排序。
事前準備
如要建立 RUM 擴充功能,您必須具備 alloydbsuperuser 資料庫角色。
AlloyDB 管理員 (roles/alloydb.admin) IAM 角色可授予 AlloyDB 資源的完整控制權,但不會授予 alloydbsuperuser 資料庫角色。如要建立擴充功能,管理員必須明確授予您 alloydbsuperuser 資料庫角色。
如要進一步瞭解如何授予角色,請參閱「將 IAM 使用者或服務帳戶新增至叢集」。
建立 RUM 擴充功能
每個資料庫都必須建立一次 RUM 擴充功能。
- 使用
psql或其他用戶端連線至 AlloyDB 資料庫。詳情請參閱「連線至叢集執行個體」。 執行下列 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 |
依其他資料欄排序的陣列搜尋。 | 不適用 |
基本全文搜尋的索引
如要進行標準 Text Search,且需要快速排名和詞組搜尋功能,請使用 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;在新的
search_vector資料欄上建立 RUM 索引: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 運算子類別,縮減索引大小並提升更新速度。這個類別會儲存每個詞素的雜湊,而非完整詞素。這種做法會產生較小的索引,但不支援前置字元搜尋。以下範例假設您有一個名為 documents 的資料表,其中包含 search_vector 資料欄。
使用雜湊運算子類別建立 RUM 索引:
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 運算子類別為陣列資料欄建立索引,例如標記清單。這樣一來,您就能有效率地查詢與其他陣列重疊 (&&)、包含其他陣列 (@>) 或包含在其他陣列中 (<@) 的陣列。以下範例會在 documents 資料表中新增 tags 資料欄。
新增
tags欄並填入資料:ALTER TABLE documents ADD COLUMN tags TEXT[]; INSERT INTO documents (title, content, tags) VALUES ( 'Title4', 'Sample Text', ARRAY['ai', 'ml'] );在名為
tags的TEXT[]資料欄上建立 RUM 索引: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 的資料表。
在
documents資料表中新增一般整數欄,例如rating:ALTER TABLE documents ADD COLUMN rating INT; UPDATE documents SET rating = floor(random() * 5 + 1);在
rating資料欄建立 RUM 索引: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 時間戳記資料欄。
建立使用雜湊運算子類別並包含
published_at時間戳記的 RUM 索引: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!'));在
query_text資料欄上建立 RUM 索引: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 時間戳記資料欄。
在包含
published_at時間戳記的tags資料欄上建立 RUM 索引: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;
後續步驟
- 瞭解全文搜尋。
- 瞭解如何執行混合型向量相似度搜尋。