查询概览

<ph type="x-smartling-placeholder">

本页面介绍了 SEARCH 函数和增强型查询模式,它们分别是 用于执行全文搜索 Spanner 表的查询。

查询搜索索引

Spanner 提供了 SEARCH 函数,供搜索索引查询使用。一个示例用例是 用户可在搜索框中输入文字的应用 将用户输入直接发送到 SEARCH 函数。然后,“SEARCH”函数会使用搜索索引查找该文本。

SEARCH 函数需要两个参数:

  • 搜索索引名称
  • 原始搜索查询

SEARCH 函数仅在定义搜索索引时有效。SEARCH 函数可与任何任意 SQL 结构(例如过滤器、汇总或联接)结合使用。

SEARCH 函数不能与事务查询一起使用。

以下查询使用 SEARCH 函数返回标题中包含 fridaymonday 的所有专辑:

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'friday OR monday')

原始搜索查询和 rquery 语言

SEARCH 函数的第二个参数是原始搜索查询。 Spanner 使用名为 rquery 的域专用语言 (DSL)。

在将输入字符串拆分为不同的术语时,rquery 语言遵循与纯文本分词器相同的规则。这包括亚洲语言细分。

如需了解如何使用 rquery,请参阅 rquery 语法

增强型查询模式

Spanner 提供两种全文搜索模式:一种是基于令牌的基本搜索,另一种是名为 enhance_query 的更高级搜索。启用后, enhance_query 用于扩展搜索查询,以包含相关字词和同义词, 增加找到相关结果的可能性。

要启用此选项,请设置可选参数 enhance_query=>trueSEARCH 函数。例如,搜索查询 hotl cal 与专辑匹配 Hotel California

SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'hotl cal', enhance_query=>true)

enhance_query 模式是一种查询时选项。而不会影响标记化。 无论是否使用 enhance_query,您都可以使用相同的搜索索引。

Google 会不断改进查询优化算法。作为 因此,使用 enhance_query == true 的查询产生的结果可能会略有不同 效果。

启用 enhance_query 模式后,SEARCH 函数要查找的字词数量可能会增加,这可能会略微增加延迟时间。

例如,以下查询使用 3 秒的超时,如果 enhance_query不可用:

@{require_enhance_query=true, enhance_query_timeout_ms=3000}
SELECT AlbumId
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, 'fast car', enhance_query=>true)

如需详细了解如何使用 enhance_query 选项,请参阅 SEARCH 函数

SQL 查询要求

SQL 查询必须满足几个条件才能使用搜索索引。 如果不符合这些条件,查询会使用替代查询计划 还是在没有替代方案时失败

查询必须满足以下条件:

  • SEARCHSEARCH_SUBSTRING 函数需要搜索索引。Spanner 不支持对基表或二级索引进行查询时使用这些函数。

  • 分区索引中的所有分区列都必须由查询的 WHERE 子句中的等式条件所约束。

    例如,如果搜索索引定义为 PARTITION BY x, y,则 查询必须在 x = <parameter or constant> AND y = <parameter or constant>WHERE 子句中包含连接词。如果缺少此类条件,查询优化器将不会考虑该搜索索引。

  • SEARCHSEARCH_SUBSTRING 运算符引用的所有 TOKENLIST 列都必须在同一搜索索引中编入索引。

    例如,请考虑以下表和索引定义:

    CREATE TABLE Albums (
        AlbumId STRING(MAX) NOT NULL,
        AlbumTitle STRING(MAX),
        AlbumStudio STRING(MAX),
        AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumTitle)) HIDDEN,
        AlbumStudio_Tokens TOKENLIST AS (TOKENIZE_FULLTEXT(AlbumStudio)) HIDDEN
      ) PRIMARY KEY(AlbumId);
    
      CREATE SEARCH INDEX AlbumsTitleIndex ON Albums(AlbumTitle_Tokens);
      CREATE SEARCH INDEX AlbumsStudioIndex ON Albums(AlbumStudio_Tokens);
    

    以下查询会失败,因为没有单个搜索索引同时为 AlbumTitle_TokensAlbumStudio_Tokens 编制索引:

    SELECT AlbumId
    FROM Albums
    WHERE SEARCH(AlbumTitle_Tokens, @p1) AND SEARCH(AlbumStudio_Tokens, @p2)
    
  • 如果排序顺序列可以为 Null,则架构和查询都必须 排除排序顺序列为 NULL 的行。如需了解详情,请参阅搜索索引排序顺序

  • 如果搜索索引采用了 NULL 过滤,则查询必须包含与索引中使用的 NULL 过滤表达式相同的表达式。如需了解详情,请参阅已过滤 null 的搜索索引

  • DML、分区 DML 或分区查询不支持搜索索引搜索函数

  • 搜索索引搜索功能 通常用于 只读事务。 如果应用要求允许使用过时结果,我们建议运行搜索查询时,过时时长应至少为 10 秒。如需了解详情,请参阅读取过时数据。这是 特别适用于扇出到多个 Paxos 的大型搜索查询 群组。

    搜索索引搜索功能 不推荐 读写事务。 在执行期间,搜索查询会锁定整个索引分区;因此,读写事务中的搜索查询速率过高可能会导致锁争用,进而导致延迟时间激增。默认情况下,搜索索引 将在读写事务中自动选中如果查询被强制 在读写事务中使用搜索索引会默认失败。它会 也会失败。您可以使用 @{ALLOW_SEARCH_INDEXES_IN_TRANSACTION=TRUE} 语句级提示替换此行为(但查询仍容易发生锁争用)。

在满足索引条件后,查询优化器会尝试 加快非文本查询条件(例如 Rating > 4)。如果搜索索引 未包含相应的 TOKENLIST 列,则条件不符合 并且一直处于 残差条件

查询参数

rquery 和 OFFSET 等其他参数均指定为字面量或查询参数。我们建议您使用查询参数进行全文搜索,而不是使用字符串字面量。

索引选择

Spanner 通常会为查询选择最高效的索引 来根据模型估算转化不过,FORCE_INDEX 提示会明确指示 Spanner 使用特定搜索索引。例如, 下面展示了如何强制 Spanner 使用 AlbumsIndex

SELECT AlbumId
FROM Albums @{FORCE_INDEX=AlbumsIndex}
WHERE SEARCH(AlbumTitle_Tokens, "fifth symphony")

如果指定的搜索索引不符合条件, 查询会失败,即使存在其他符合条件的搜索索引也是如此。

搜索结果中的代码段

摘要是从给定字符串中提取的一段文本,可让用户大致了解搜索结果的内容以及该结果与其查询相关的原因。

例如,Gmail 会使用摘要来指明电子邮件中 与搜索查询匹配:

代码段列表

让数据库生成代码段有诸多好处:

  1. 便捷:您无需实现逻辑即可根据搜索查询生成摘要。
  2. 效率:代码段可减小服务器的输出大小。

SNIPPET 函数用于创建该代码段。它会返回 原始字符串值以及要突出显示的字符的位置。通过 然后,客户可以选择如何向最终用户显示摘要(例如, 使用突出显示或粗体文字)。SNIPPET 函数可移除所有 HTML 标记 原始字符串。

例如,以下代码使用 SNIPPETAlbumTitle 检索文本:

SELECT AlbumId, SNIPPET(AlbumTitle, "Fast Car")
FROM Albums
WHERE SEARCH(AlbumTitle_Tokens, "Fast Car")

后续步骤