全文索引
在 seekdb 中,全文索引可以应用于 CHAR、VARCHAR 和 TEXT 类型的列。此外,seekdb 允许在主表上建立多个全文索引,并且对于同一列也可以建立多个全文索引。
非分区表和分区表上有无主键都可以创建全文索引,创建全文索引限制如下:
- 全文索引仅支持应用于
CHAR、VARCHAR和TEXT类型的列。 - 当前版本只支持创建局部(
LOCAL)全文索引。 - 创建全文索引时不可以指定
UNIQUE关键字。 - 如果要创建涉及多列的全文索引,则必须确保这些列具有相同的字符集。
通过使用这些语法和规则,seekdb 的全文索引功能提供了对文本数据的高效搜索和搜索能力。
DML 操作
对于已创建包含全文索引的表,支持 INSERT INTO ON DUPLICATE KEY、REPLACE INTO、多表的更新/删除、以及可更新视图等复杂 DML 操作。
示例如下:
-
INSERT INTO ON DUPLICATE KEY:
INSERT INTO articles VALUES ('seekdb', 'Fulltext search index support insert into on duplicate key')
ON DUPLICATE KEY UPDATE title = 'seekdb'; -
REPLACE INTO:
REPLACE INTO articles(title, context) VALUES ('seekdb', 'Fulltext search index support replace'); -
多表的更新/删除。
-
创建表
tbl1。CREATE TABLE tbl1 (a int PRIMARY KEY, b text, FULLTEXT INDEX(b)); -
创建表
tbl2。CREATE TABLE tbl2 (a int PRIMARY KEY, b text); -
多个表的更新(
UPDATE)语句。UPDATE tbl1 JOIN tbl2 ON tbl1.a = tbl2.a
SET tbl1.b = 'dddd', tbl2.b = 'eeee';UPDATE tbl1 JOIN tbl2 ON tbl1.a = tbl2.a SET tbl1.b = 'dddd';UPDATE tbl1 JOIN tbl2 ON tbl1.a = tbl2.a SET tbl2.b = tbl1.b; -
多个表的删除(
DELETE)语句。DELETE tbl1, tbl2 FROM tbl1 JOIN tbl2 ON tbl1.a = tbl2.a;DELETE tbl1 FROM tbl1 JOIN tbl2 ON tbl1.a = tbl2.a;DELETE tbl1 FROM tbl1 JOIN tbl2 ON tbl1.a = tbl2.a;
-
-
可更新视图 DML。
-
创建视图
fts_view。CREATE VIEW fts_view AS SELECT * FROM tbl1; -
INSERT语句用于可更新视图。INSERT INTO fts_view VALUES(3, 'cccc'), (4, 'dddd'); -
UPDATE语句用于可更新视图。UPDATE fts_view SET b = 'dddd';UPDATE fts_view JOIN normal ON fts_view.a = tbl2.a
SET fts_view.b = 'dddd', tbl2.b = 'eeee'; -
DELETE语句用于可更新视图。DELETE FROM fts_view WHERE b = 'dddd';DELETE tbl1 FROM fts_view JOIN tbl1 ON fts_view.a = tbl1.a AND 1 = 0;
-
全文索引的分词器
seekdb 的全文索引功能支持多种内置分词器,帮助用户根据业务场景选择最优的文本分词策略。默认分词器为 Space分词器,其他分词器需通过WITH PARSER参数显式指定。
分词器列表:
- Space 分词器
- Basic English 分词器
- IK 分词器
- Ngram 分词器
- jieba 分词器
配置方法示例:
在创建或修改表时,通过 CREATE TABLE/ALTER TABLE 语句在为表创建全文索引时,设置参数 WITH PARSER tokenizer_option,指定全文索引的分词器类型。更多分词器的属性参数设置参考 创建索引。
CREATE TABLE tbl2(id INT, name VARCHAR(18), doc TEXT,
FULLTEXT INDEX full_idx1_tbl2(name, doc)
WITH PARSER NGRAM
PARSER_PROPERTIES=(ngram_token_size=3));
-- 修改现有表的全文索引分词器
ALTER TABLE tbl2(id INT, name VARCHAR(18), doc TEXT,
FULLTEXT INDEX full_idx1_tbl2(name, doc)
WITH PARSER NGRAM
PARSER_PROPERTIES=(ngram_token_size=3)); -- Ngram示例
Space 分词器(默认)
概念:
- 以空格、标点符号(如逗号、句号)或非字母 数字字符(除下划线
_外)为分隔符拆分文本。 - 分词结果仅包含长度在
min_token_size(默认 3)到max_token_size(默认 84)之间的有效词元。 - 中文字符被视为单个字符处理。
适用场景:
- 英文等以空格分隔的语言(如 “apple watch series 9”)。
- 中文以人工添加分隔符的场景(如 “南京 长江大桥”)。
分词效果:
OceanBase(rooteoceanbase)>select tokenize("南京市长江大桥有1千米长,详见www.XXX.COM, 邮箱xx@OB.COM,一平方公里也很小 hello-word h_name", 'space');
+-------------------------------------------------------------------------------------------------------------+
| tokenize("南京市长江大桥有1千米长,详见www.XXX.COM, 邮箱xx@OB.COM,一平方公里也很小 hello-word h_name", 'space') |
+-------------------------------------------------------------------------------------------------------------+
|["详见www", "一平方公里也很小", "xxx", "南京市长江大桥有1千米长", "邮箱xx", "word", "hello”, "h_name"] |
+-------------------------------------------------------------------------------------------------------------+
示例说明:
- 空格、逗号、句号等符号作为分隔符,中文连续字符视为单词。
Basic English(Beng)分词器
概念:
- 与 Space 分词器类似,但不保留下划线
_,将其视为分隔符。 - 适用于英文短语分隔,但对无空格术语(如 “iPhone15”)切分效果有限。
适用场景:
- 英文文档的基础搜索(如日志、评论)。
分词效果:
OceanBase(rooteoceanbase)>select tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'beng');
+-----------------------------------------------------------------------------------------------------------------------+
| tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM,邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'beng') |
+-----------------------------------------------------------------------------------------------------------------------+
|["详见www", "一平方公里也很小", "xxx", "南京市长江大桥有1千米长", "邮箱xx", "word", "hello", "name"] |
+-----------------------------------------------------------------------------------------------------------------------+
示例说明:
- 下划线
_被切分,与Space分词器的核心差异在于对_的处理。
Ngram 分词器
概念:
- 固定n值分词:默认
n=2,将连续非分隔符字符拆分为长度为n的子序列。 - 分隔符判定规则同 Space 分词器(保留
_和数字字母)。 - 不支持长度限制参数,输出所有可能的
n长度词元。
适用场景:
- 短文本模糊匹配(如用户 ID、订单号)。
- 需要固定长度特征提取的场景(如密码策略分析)。
分词效果:
OceanBase(rooteoceanbase)>select tokenize("南京市长江 大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'ngram');
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM, 一平方公里也很小 hello-word h_name", 'ngram') |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|["邮箱", "ww", "大桥", “ob", "me", "里也", "or", "_n", "千米", "很小", "米长", "ll", "箱x", "公里", "见w", "co", "也很", "1千", "京市", "lo", "江大", "el", "rd", "一平", "方公", "he", "am", "南京", "h_", "市长", "wo", "xx", "长江", "有1", "na", "详见", "平方", "om", "桥有" |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
示例说明:
- 默认
n=2时,输出所有连续2字符的词元,包括重叠部分。
Ngram2 分词器
概念:
- 支持动态n值范围:通过
min_ngram_size和max_ngram_size参数设置词元长度范围。 - 适用于需要多长度词元覆盖的场景。
适用场景: 同时需要多个固定长度词元的场景。
用 ngram2 分词器时,需注意其内存占用较高,比如设置 min_ngram_size 和 max_ngram_size 参数范围较大时,会生成大量词元组合,可能导致资源消耗过大。
分词效果:
OceanBase(rooteoceanbase)>select tokenize("南京市长江大桥1千米", 'ngram2', '[{"additional_args":[{"min_ngram_size": 4},{"max_ngram_size": 6}]}]');
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tokenize("南京市长江大桥1千米", 'ngram2', '[{"additional_args":[{"min_ngram_size": 4},{"max_ngram_size": 6}]}]') |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ["长江大桥", "大桥1千", "江大桥1千", "市长江大桥", "京市长江", "江大桥1", "南京市长", "市长江大", "大桥1千米", "江大桥1千米", "市长江大桥1", "长江大桥1", "南京市长江", "桥1千米", "南京市长江大", "长江大桥1千", "京市长江大桥", "京市长江大" |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
示例说明:
- 输出长度在4-6字符的所有连续子序列,且词元可重叠。
IK 分词器
概念:
-
基于开源工具 IK Analyzer 的中文分词器,支持两种模式:
- Smart 模式:优先输出长词,减少切分数量(如“南京市”不切分为“南京”“市”)。
- Max Word 模式:输出所有可能的短词(如“南京市”切分为“南京”“市”)。
-
自动识别英 文单词、邮箱、URL(不含
://)、IP 地址等格式。
适用场景:中文分词
业务场景:
-
电商商品描述搜索(如“华为Mate60”精准匹配)。
-
社交媒体内容分析(如用户评论的关键词提取)。
-
Smart 模式:会保证一个字符只会归属一个词汇,没有任何交叠,且保证组成单个词的长度尽可能长,组成的词汇尽可能少。会尝试将数词和量词组合起来,作为一个词汇输出。
OceanBase(rooteoceanbase)>select tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM 192.168.1.1 http://www.baidu.com hello-word hello_word", 'IK', '[{"additional_args":[{"ik_mode": "smart"}]}]');
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM 192.168.1.1 http://www.baidu.com hello-word hello_word", 'IK', '[{"additional_args":[{"ik_mode": "smart"}]}]') |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|["邮箱", "hello_word", "192.168.1.1", "hello-word", "长江大桥", "www.baidu.com", "www.xxx.com", "xx@ob.com", "长", "http", "1千米", "详见", "南京市", "有"] |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
- max_word 模式: 会把同一个字符包含到不同的分词中, 尽可能多的提供可能的词汇。
OceanBase(rooteoceanbase)>select tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM", 'IK', '[{"additional_args":[{"ik_mode": "max_word"}]}]');
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tokenize("南京市长江大桥有1千米长,详见WWW.XXX.COM, 邮箱xx@OB.COM", 'IK', '[{"additional_args":[{"ik_mode": "max_word"}]}]') |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|["米", "长江大桥", "市长", "干", "南京市", "南京", "千米", "xx", "www.xxx.com", "长", "www", "xx@ob.com", "长江", "ob", "XXX", "com", "详见", "l", "有", "大桥", "邮箱"] |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
jieba 分词器
概念:基于 Python 生态开源工具 jieba 的分词器,支持精准、全模式及搜索引擎模式。
特点:
- 精准模式:严格按词典切分(如“不能”不切分为“不”“能” )。
- 全模式:列出所有可能的切分组合。
- 搜索引擎模式:平衡精准与召回率(如“南京市长江大桥”→“南京”“市长”“长江大桥”)。
- 支持自定义词典和新词发现,兼容多语言(中文、英文、日文等)。
适用场景:
- 医疗/科技领域术语分析(如“人工智能”精准切分)。
- 多语言混合文本处理(如中英混杂的社交媒体内容)。
jieba 分词器插件需要您自行安装,编译机安装步骤,详见分词器插件。
当前分词器插件为实验特性,暂不建议在生产环境使用。
分词器选择策略
| 业务场景 | 推荐分词器 | 理由 |
|---|---|---|
| 英文商品标题搜索 | Space 或 Basic English | 简单高效,符合英文分词习惯。 |
| 中文商品描述搜索 | IK 分词器 | 精准识别中文术语,支持自定义词典。 |
| 日志模糊匹配(如错误代码) | Ngram 分词器 | 无需词典,覆盖无空格文本的模糊查询需求。 |
| 科技论文关键词提取 | jieba 分词器 | 支持新词发现与复杂模式切换。 |
相关文档
有关创建全文索引的详细信息,参见 创建索引 中的 创建全文索引 章节。