本页介绍了如何执行混合全文和非文本数据的搜索。
执行混合全文搜索和非文本搜索
搜索索引支持全文、完全匹配和数字列。您可以在 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 中,该查询会提取Title
中包含字词“car”且评分高于 4 的所有文档,然后滤除赞数不至少为 1000 的文档。如果几乎所有影集的标题中都包含“汽车”一词,并且几乎所有影集的评分都为 5 分,但很少有影集获得 1, 000 次赞,那么此查询会使用大量资源。在这种情况下,对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