执行子字符串搜索

除了完整的 token 匹配之外,Spanner 搜索索引还支持子字符串搜索。本页介绍了如何在 Spanner 中执行子字符串搜索,作为全文搜索的一部分。

子字符串搜索具有以下特征:

  • 不区分大小写,丢弃大多数标点符号,并对空格进行标准化。
  • 不进行中文、日文、韩文 (CJK) 分词,因为部分 CJK 查询经常分词错误。
  • 对于多个搜索字词,结果必须包含每个字词中的子字符串。例如,'happ momen'"happy moment" 匹配,因为这两个子字符串都在文本中找到。它与 "happy day" 不匹配。

示例

存储的文本 子字符串查询 匹配
Bridge over Troubled Water ridg roub
Bridge over Troubled Water ridg , roub
Bridge over Troubled Water over brid
Bridge over Troubled Water ate bridge
Bridge over Troubled Water Bridge bridge bridge
Bridge over Troubled Water bri trou ter
Bridge over Troubled Water bri dge
Bridge over Troubled Water troubledwater
Bridge over Troubled Water trubled

对于子字符串搜索,请在 TOKENLIST 列定义中使用 TOKENIZE_SUBSTRING 函数,如以下 DDL 示例所示:

GoogleSQL

CREATE TABLE Albums (
AlbumId STRING(MAX) NOT NULL,
AlbumTitle STRING(MAX),
AlbumTitle_Tokens TOKENLIST AS (TOKENIZE_SUBSTRING(AlbumTitle)) HIDDEN
) PRIMARY KEY(AlbumId);

PostgreSQL

此示例使用 spanner.tokenize_substring

CREATE TABLE albums (
albumid character varying NOT NULL,
albumtitle character varying,
albumtitle_tokens spanner.tokenlist
    GENERATED ALWAYS AS (spanner.tokenize_substring(albumtitle)) VIRTUAL HIDDEN,
PRIMARY KEY(albumid));

在 SQL 查询中,请在 WHERE 子句中使用 SEARCH_SUBSTRING 函数。例如,以下查询会匹配上一个示例中创建的表中的标题为“happy”的专辑:

GoogleSQL

SELECT Album
FROM Albums
WHERE SEARCH_SUBSTRING(AlbumTitle_Tokens, 'happ');

PostgreSQL

此示例使用 spanner.search_substring

SELECT album
FROM albums
WHERE spanner.search_substring(albumtitle_tokens, 'happ');

TOKENIZE_SUBSTRING 会为每个 token 生成 N 元语法,并将这些 N 元语法存储在搜索索引中。要生成的 N 元语法的最小和最大长度通过可选参数进行配置。

子字符串搜索索引所需的存储空间是相同数据的全文本索引的 10-30 倍,因为词元化会生成更多 token。特别是当 ngram_size_minngram_size_max 之间的差异增大时,这种情况尤其明显。子字符串查询也会使用更多资源来执行。

TOKENIZE_FULLTEXT 一样,您可以将 TOKENIZE_SUBSTRING 配置为使用特定类型的内容。

除了基本子字符串搜索之外,SEARCH_SUBSTRING 还支持相对搜索模式。相对搜索可对子字符串搜索结果进行优化。

如需启用相对搜索模式,请将 TOKENIZE_SUBSTRINGrelative_search_types 参数设置为包含受支持相对搜索类型的元素的非空数组。

在词元化中启用相对搜索后,SEARCH_SUBSTRING 可以使用以下相对搜索类型执行查询:

  • phrase:匹配连续子字符串

    示例

    存储的文本 子字符串查询。 匹配
    Bridge over Troubled Water bridge over
    Bridge over Troubled Water Bridge bridge bridge
    Bridge over Troubled Water brid over
    Bridge over Troubled Water ridge over trouble
    Bridge over Troubled Water bridge ove troubled
    Bridge over Troubled Water idge ove
    Bridge over Troubled Water idge , ove
    Bridge over Troubled Water RIDGE OVE
    Bridge over Troubled Water bridge water
  • value_prefix:匹配连续子字符串,并且匹配必须从值的开头开始。从概念上讲,这类似于针对大小写和空格规范化的字符串的 STARTS_WITH 函数。

    示例

    存储的文本 子字符串查询 匹配
    Bridge over Troubled Water bridge over
    Bridge over Troubled Water bridge , over
    Bridge over Troubled Water ridge over
    Bridge over Troubled Water troubled water
  • value_suffix:匹配连续子字符串,并且匹配必须在值的末尾。从概念上讲,这类似于针对大小写和空格规范化的字符串的 ENDS_WITH 函数。

    示例

    存储的文本 子字符串查询。 匹配
    Bridge over Troubled Water troubled water
    Bridge over Troubled Water troubled ; water
    Bridge over Troubled Water roubled water
    Bridge over Troubled Water troubled wate
    Bridge over Troubled Water trouble water
    Bridge over Troubled Water bridge over
  • word_prefix: 类似于 value_prefix,但字符串必须在字词边界(而不是值边界)处匹配。

    示例

    存储的文本 子字符串查询 匹配
    Bridge over Troubled Water over trouble
    Bridge over Troubled Water Over , trouble
    Bridge over Troubled Water troub water
    Bridge over Troubled Water over water
    Bridge over Troubled Water ove troubled
    Bridge over Troubled Water ver troubled
  • word_suffix:与 value_suffix 类似,但字符串必须在字词边界末尾进行匹配。

    示例

    存储的文本 子字符串查询 匹配
    Bridge over Troubled Water ver troubled
    Bridge over Troubled Water over trouble
    Bridge over Troubled Water over water
    Bridge over Troubled Water ove troubled

后续步骤