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

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

搜索索引支持全文、完全匹配和数字列。您可以在 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,查询会提取包含字词“car”的所有文档 Title 且评分超过 4 分,则它会过滤掉符合 被顶的次数少于 1000 次。此查询会使用大量资源,因为几乎不需要 所有专辑都使用“汽车”一词几乎所有人都有 评分为 5 分,但很少有专辑能获得 1000 次赞。在这种情况下,索引编制 LikesRating 类似,可以节省资源。

    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
    

后续步骤