除了完整的 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_min
和 ngram_size_max
之间的差异增大时,这种情况尤其明显。子字符串查询也会使用更多资源来执行。
与 TOKENIZE_FULLTEXT
一样,您可以将 TOKENIZE_SUBSTRING
配置为使用特定类型的内容。
启用相对子字符串搜索
除了基本子字符串搜索之外,SEARCH_SUBSTRING
还支持相对搜索模式。相对搜索可对子字符串搜索结果进行优化。
如需启用相对搜索模式,请将 TOKENIZE_SUBSTRING
的 relative_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 否
后续步骤
- 了解全文搜索查询。
- 了解如何对搜索结果进行排名。
- 了解如何对搜索结果进行分页。
- 了解如何混合使用全文本查询和非文本查询。
- 了解如何搜索多个列。