Manticore Search
现在支持
在 CREATE TABLE 语句中直接内联指定分词字典设置。此增强功能消除了在配置停用词、例外词、词形和无命中词时对外部文件的需求,使表创建更加流畅且易于部署。
新功能
RT 模式 中现在有四种新的配置选项:
stopwords_list- 在表定义中直接指定停用词exceptions_list- 在线定义分词例外词wordforms_list- 在不使用外部文件的情况下配置词形映射hitless_words_list- 在表创建时设置无命中词
所有这些选项都使用分号(;)作为条目之间的分隔符,使其在 SQL 和 HTTP JSON 接口中易于使用。
它们解决的问题
传统上,配置分词字典需要创建 Manticore 在表创建期间读取的外部文件。虽然这种方法在许多场景中效果良好,但它带来了几个挑战:
文件权限问题
在受限用户账户下运行的 Web 应用程序通常难以在同时满足以下条件的目录中创建文件:
- 可被 Web 服务器进程写入
- 可被 Manticore 守护进程进程读取
这在共享托管环境中尤其成问题,其中 Web 应用程序在受限用户账户下运行(例如在 Virtualmin 或类似控制面板设置中),用户主目录通常仅对所有者可读,而系统目录可能具有严格的权限。
粘滞目录问题
使用系统临时目录(如 /tmp)会引入另一个问题:这些目录上的粘滞位会阻止对停用词文件进行适当的清理。当索引频繁重建时,孤立文件会累积,消耗磁盘空间并造成维护困扰。
文件生命周期管理
当表频繁创建和销毁时,管理相关的分词字典文件变得繁琐。开发人员必须:
- 在表创建之前创建文件
- 确保文件可被 Manticore 读取
- 记得在表删除时清理文件
这种手动过程容易出错,可能导致文件系统混乱。
新选项
新的 *_list 选项允许您直接在 CREATE TABLE 语句中指定分词字典设置。使用外部文件时,SHOW CREATE TABLE 会显示文件路径,您需要在单独的文件中维护字典内容;使用内联选项时,您永远不会创建或引用外部路径。字典内容存在于 DDL 中(内部仍会以文件形式存储在表目录中,与文件路径相同)。SHOW CREATE TABLE 会内联显示完整的字典设置(例如 stopwords_list = 'a; the; an'),因此表定义在一个语句中自包含,更易于版本控制和复制或共享。表定义可以在不同环境中移植。
使用示例
停用词
而不是创建停用词文件:
-- Old way (requires external file)
CREATE TABLE products(title text, price float)
stopwords = '/usr/local/manticore/data/stopwords.txt'
现在可以内联指定停用词:
-- New way (no external file needed)
CREATE TABLE products(title text, price float)
stopwords_list = 'a; the; an; and; or; but'
例外词
例外词(同义词)可以内联定义:
CREATE TABLE products(title text, price float)
exceptions_list = 'AT&T => ATT; MS Windows => ms windows; C++ => cplusplus'
词形
词形映射可以直接指定:
CREATE TABLE products(title text, price float)
wordforms_list = 'walks > walk; walked > walk; walking > walk'
无命中词
无命中词可以内联配置:
CREATE TABLE products(title text, price float)
hitless_words_list = 'hello; world; test'
组合多个选项
可以在单个 CREATE TABLE 语句中组合所有这些选项:
CREATE TABLE products(title text, price float)
stopwords_list = 'a; the; an'
exceptions_list = 'AT&T => ATT'
wordforms_list = 'walks > walk; walked > walk'
hitless_words_list = 'hello; world'
何时使用内联配置
内联配置在以下情况下理想:
- 小型到中型列表:列表大小合理(通常在几百个条目以下)。对于非常大的字典,外部文件可能仍然更实用。
- 动态表创建:您的应用程序以编程方式创建和销毁表,使文件管理变得繁琐。
- 受限文件系统访问:您在具有有限文件系统权限的环境中运行(共享托管、容器等)。
- 简化部署:您希望避免将额外文件作为部署过程的一部分进行管理。
- 频繁索引重建:表频繁重建,使文件清理成为维护负担。
何时使用外部文件更好
尽管内联配置很方便,但在以下情况下外部文件仍然是更好的选择:
- 大型字典:当您有数千个条目时,外部文件更易于管理,不会使
CREATE TABLE语句膨胀。 - 共享字典:如果相同的字典在多个表中使用,外部文件允许您定义一次并从多个表中引用,减少重复。
- 版本控制:外部文件可以轻松地在版本控制系统中跟踪,使审查更改和维护历史更容易。
- 动态更新:如果您需要在不重新创建表的情况下更新字典,可以修改外部文件,然后使用
ALTER TABLE <table_name> RECONFIGURE应用更改。对于 RT 表,这会使新的分词设置对新文档生效(现有文档保持不变)。对于普通表,需要轮换以获取修改后的字典文件中的更改。 - 复杂格式:非常复杂的词形或例外规则可能更容易在带有适当格式和注释的专用文件中编辑。
- 遗留系统:如果您已经有良好维护的外部字典文件,除非您面临内联配置解决的具体问题,否则无需迁移。
格式细节
分隔符
所有 *_list 选项使用分号 (;) 分隔条目。分号周围的空格会被标准化,因此 'word1; word2' 和 'word1 ; word2' 是等效的。
转义
如果需要在值本身中使用分号(而不是作为分隔符),请使用反斜杠进行转义:\;。例如,如果要映射包含分号的源形式:
exceptions_list = 'test\;value => testvalue; another => mapping'
这会创建两个映射:
test;value(带分号)→testvalueanother→mapping
转义后的分号(\;)被视为字面分号字符,而不是条目之间的分隔符。
词形格式
词形支持使用 > 和 => 作为分隔符:
wordforms_list = 'word1 > form1; word2 => form2'
例外格式
例外使用 => 作为源形式和目标形式之间的分隔符:
exceptions_list = 'source form => destination form'
注意:使用 exceptions_list 时,您可能会在 searchd 日志中看到关于 mapping token (=>) not found 的警告,这些警告是无害的,可以安全忽略——例外功能即使有这些消息也能正常工作。这些警告发生在内部文件处理期间,不会影响实际的例外映射行为。
示例:停用词、词形和例外一起使用
以下是在单个表中使用内联停用词、词形和例外的实用示例。词形将变体标准化为单一形式(例如 "learning" → "learn");例外将缩写映射到标准化形式(例如 "JS" → "javascript"),使得 "JS" 和 "JavaScript" 匹配相同文档。在例外目标中使用小写,以便与 charset_table 生成的标记形式匹配。
-- Create a table with inline stopwords, wordforms, and exceptions
CREATE TABLE articles(id bigint, title text)
stopwords_list = 'a; the; an; and; or; but; in; on; at; to; for; of; with'
wordforms_list = 'learning > learn; programming > program; reference > refer; introduction > intro; complete > complet; basics > basic'
exceptions_list = 'JS => javascript; ML => machine learning';
-- Insert test data
INSERT INTO articles VALUES
(1, 'The Quick Guide to Python Programming'),
(2, 'A Complete Reference for JavaScript'),
(3, 'An Introduction to Machine Learning'),
(4, 'Python Programming Basics'),
(5, 'Getting Started with JS');
停用词:包含或不包含停用词的查询匹配相同文档。
SELECT * FROM articles WHERE MATCH('python');
| id | title |
|---|---|
| 1 | The Quick Guide to Python Programming |
| 4 | Python Programming Basics |
SELECT * FROM articles WHERE MATCH('the python');
| id | title |
|---|---|
| 1 | The Quick Guide to Python Programming |
| 4 | Python Programming Basics |
短语搜索:停用词在匹配时被跳过,但仍会影响位置(可通过 stopword_step 调整)。
SELECT * FROM articles WHERE MATCH('"the quick"');
| id | title |
|---|---|
| 1 | The Quick Guide to Python Programming |
词形:通过词形 "learn" 匹配 "Learning"。
SELECT * FROM articles WHERE MATCH('learn');
| id | title |
|---|---|
| 3 | An Introduction to Machine Learning |
例外:映射 JS => javascript 将文本或查询中的 "JS" 标准化为 "javascript"。由于目标是小写,它会匹配 charset_table 为 "JavaScript" 生成的标记形式,因此 MATCH('JavaScript') 和 MATCH('JS') 返回相同的行。
SELECT * FROM articles WHERE MATCH('JavaScript');
| id | title |
|---|---|
| 2 | A Complete Reference for JavaScript |
| 5 | Getting Started with JS |
SELECT * FROM articles WHERE MATCH('JS');
| id | title |
|---|---|
| 2 | A Complete Reference for JavaScript |
| 5 | Getting Started with JS |
优势总结
- 无需文件管理:消除了创建、管理和清理外部文件的需求
- 简化部署:配置是表定义的一部分,使部署更加直接
- 权限独立:无需在 Web 服务器和 Manticore 进程之间处理文件系统权限问题
- 更适合自动化:更容易脚本化和自动化表创建
- 自包含且自文档化:表配置在
CREATE TABLE语句中完整,SHOW CREATE TABLE显示完整的字典内容内联,因此定义易于共享和版本控制,无需管理单独的字典文件
迁移路径
如果您当前使用外部文件,可以轻松迁移到内联配置:
- 读取现有文件内容
- 将格式转换为使用分号作为分隔符
- 在
CREATE TABLE语句中将文件路径替换为*_list选项
例如,如果您有一个包含以下内容的 stopwords.txt 文件:
a
the
an
and
您可以将其转换为:
stopwords_list = 'a; the; an; and'
结论
新的内联标记化字典配置选项(stopwords_list、exceptions_list、wordforms_list 和 hitless_words_list)提供了一种更干净、更易于维护的方式来配置标记化设置。它们在文件管理具有挑战性的环境中或当您希望简化部署流程并保持表定义自包含时特别有价值。虽然外部文件仍支持大型字典,但内联配置为大多数用例提供了一种便捷的替代方案。
