混合使用全文查询和非文本查询

本页介绍了如何执行混合全文和非文本数据的搜索。

搜索索引支持全文、完全匹配和数字列。您可以在 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;

对此表执行的查询的行为包括:

  • RatingGenres 包含在搜索索引中。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 不会存储在索引中。以下查询会在 AlbumsIndexAlbums 之间执行回联,以便为所有匹配的相册提取 Cover

    SELECT AlbumId, Cover
    FROM Albums
    WHERE SEARCH(Title_Tokens, 'car')
      AND Rating > 4
    

后续步骤