本文档介绍了如何创建 RUM 扩展程序和创建索引,以优化 AlloyDB for PostgreSQL 中的全文搜索。它提供了常见用例的示例,包括排名、短语搜索和按时间戳排序。
准备工作
如需创建 RUM 扩展程序,您必须具有 alloydbsuperuser 数据库角色。
AlloyDB Admin (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 |
按另一列排序的数组搜索。 | 不适用 |
用于基本全文搜索的索引
对于需要快速排名和短语搜索功能的标准文本搜索,请使用 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 时间戳列。
在
tags列上创建包含published_at时间戳的 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;
后续步骤
- 了解全文搜索。
- 了解如何运行混合向量相似性 搜索。