本页介绍如何执行混合全文和非文本的搜索 数据。
执行全文和非文本混合搜索
搜索索引支持全文、完全匹配和数字列。您可以在 WHERE
子句中组合使用文本和非文本条件,方法与多列搜索查询类似。查询优化器会尝试使用搜索索引优化非文本谓词。如果
但这是不可能实现的,Spanner 会评估每行的条件,
与搜索索引相匹配的内容。未存储在搜索索引中的引用列
从基表中提取。
例如:
CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
Title STRING(MAX),
Rating FLOAT64,
Genres ARRAY<STRING(MAX)>,
Likes INT64,
Cover BYTES(MAX),
Title_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(Title)) HIDDEN,
Rating_Tokens TOKENLIST AS (TOKENIZE_NUMBER(Rating)) HIDDEN,
Genres_Tokens TOKENLIST AS (TOKEN(Genres)) HIDDEN
) PRIMARY KEY(AlbumId);
CREATE SEARCH INDEX AlbumsIndex
ON Albums(Title_Tokens, Rating_Tokens, Genres_Tokens)
STORING Likes;
此表上的查询行为包括:
Rating
和Genres
包含在搜索索引中。Spanner 使用搜索索引的 Posting 列表来加速条件的处理。SELECT Album FROM Albums WHERE Rating > 4 AND ARRAY_INCLUDES_ANY(Genres, ['jazz'])
该查询能够以任何方式组合连词、析取运算和否定运算符, 包括混合使用全文和非文本谓词。此查询 被搜索索引加速了。
SELECT Album FROM Albums WHERE (SEARCH(Title_Tokens, 'car') OR Rating > 4) AND NOT ARRAY_INCLUDES_ANY(Genres, ['jazz'])
Likes
存储在索引中,但架构没有请求 Spanner 为其可能的值构建词元索引。 因此,在Title
上存在全文谓词,而在Rating
加速,但Likes
上的谓词则不加速。在 Spanner,查询会提取包含字词“car”的所有文档Title
且评分超过 4 分,则它会过滤掉符合 被顶的次数少于 1000 次。此查询会使用大量资源,因为几乎不需要 所有专辑都使用“汽车”一词几乎所有人都有 评分为 5 分,但很少有专辑能获得 1000 次赞。在这种情况下,索引编制Likes
与Rating
类似,可以节省资源。SELECT Album FROM Albums WHERE SEARCH(Title_Tokens, 'car') AND Rating > 4 AND Likes >= 1000
Cover
不会存储在索引中。以下查询会执行 后向联接 在AlbumsIndex
和Albums
之间获取Cover
以获取所有匹配的相册。SELECT AlbumId, Cover FROM Albums WHERE SEARCH(Title_Tokens, 'car') AND Rating > 4