拼写校正,也称为:
- 自动更正
- 文本校正
- 修正拼写错误
- 键入容错
- “您是否是指?”
等等,是一种软件功能,可以建议或自动更正您输入的文本的替代方案。校正输入文本的概念可以追溯到1960年代,当时计算机科学家Warren Teitelman(也是“撤销”命令的发明者)引入了一种称为D.W.I.M.(“Do What I Mean”,即“按我的意图执行”)的计算哲学。Teitelman认为,计算机不应该仅被编程为接受格式完美的指令,而应该被编程为识别明显的错误。
第一个提供拼写校正功能的知名产品是1993年发布的Microsoft Word 6.0。
拼写校正可以通过几种方式实现,但需要注意的是,没有纯粹的程序化方法可以将您误输入的“ipone”高质量地转换为“iphone”。大多数情况下,系统必须基于某个数据集。数据集可以是:
- 一个正确拼写的单词字典,该字典可以是:
- 基于您的真实数据。这里的思路是,字典中大部分拼写是正确的,系统会尝试找到与输入单词最相似的单词(我们稍后将讨论如何使用Manticore实现这一点)。
- 或者基于与您的数据无关的外部字典。这里可能出现的问题是,您的数据和外部字典可能差异太大:字典中可能缺少一些单词,而您的数据中可能缺少其他单词。
- 不仅基于字典,还具备上下文感知能力,例如“white ber”会被校正为“white bear”,而“dark ber”会被校正为“dark beer”。上下文可能不仅仅是查询中的相邻单词,还可能包括您的位置、时间、当前句子的语法(例如是否将“there”更正为“their”)、您的搜索历史,以及几乎所有可能影响您意图的其他因素。
- 另一种经典方法是使用之前的搜索查询作为拼写校正的数据集。这在自动补全功能中被更广泛地使用,但对自动更正也适用。其思路是,用户在拼写上大多是正确的,因此我们可以使用他们搜索历史中的单词作为事实来源,即使我们没有在文档中使用这些单词或使用外部字典。此处也可以实现上下文感知。
Manticore提供了模糊搜索选项以及可用于自动拼写校正的命令CALL QSUGGEST和CALL SUGGEST。
模糊搜索功能通过考虑搜索查询中的细微变化或拼写错误,允许更灵活的匹配。它的工作方式类似于普通的SELECT SQL语句或/search JSON请求,但提供了额外的参数来控制模糊匹配行为。
注意:
fuzzy选项需要Manticore Buddy。如果不起作用,请确保已安装Buddy。
注意:
fuzzy选项不适用于多查询。
SELECT
...
MATCH('...')
...
OPTION fuzzy={0|1}
[, distance=N]
[, preserve={0|1}]
[, layouts='{be,bg,br,ch,de,dk,es,fr,uk,gr,it,no,pt,ru,se,ua,us}']
}
注意:通过SQL进行模糊搜索时,MATCH子句不应包含任何全文本运算符,除了短语搜索运算符,并且应仅包含您打算匹配的单词。
- SQL
- SQL with additional filters
- JSON
- SQL with preserve option
- JSON with preserve option
SELECT * FROM mytable WHERE MATCH('someting') OPTION fuzzy=1, layouts='us,ua', distance=2;带有附加筛选器的更复杂模糊搜索查询示例:
SELECT * FROM mytable WHERE MATCH('someting') OPTION fuzzy=1 AND (category='books' AND price < 20);POST /search
{
"table": "test",
"query": {
"bool": {
"must": [
{
"match": {
"*": "ghbdtn"
}
}
]
}
},
"options": {
"fuzzy": true,
"layouts": ["us", "ru"],
"distance": 2
}
}SELECT * FROM mytable WHERE MATCH('hello wrld') OPTION fuzzy=1, preserve=1;POST /search
{
"table": "test",
"query": {
"bool": {
"must": [
{
"match": {
"*": "hello wrld"
}
}
]
}
},
"options": {
"fuzzy": true,
"preserve": 1
}
}+------+-------------+
| id | content |
+------+-------------+
| 1 | something |
| 2 | some thing |
+------+-------------+
2 rows in set (0.00 sec)+------+-------------+
| id | content |
+------+-------------+
| 1 | hello wrld |
| 2 | hello world |
+------+-------------+
2 rows in set (0.00 sec)POST /search
{
"table": "table_name",
"query": {
<full-text query>
},
"options": {
"fuzzy": {true|false}
[,"layouts": ["be","bg","br","ch","de","dk","es","fr","uk","gr","it","no","pt","ru","se","ua","us"]]
[,"distance": N]
[,"preserve": {0|1}]
}
}
注意:如果您使用query_string,请注意它不支持除短语搜索运算符以外的全文本运算符。查询字符串应仅包含您希望匹配的单词。
fuzzy:启用或关闭模糊搜索。distance:设置匹配的莱文斯坦距离。默认值为2。preserve:0或1(默认:0)。当设置为1时,在搜索结果中保留没有模糊匹配的单词(例如,“hello wrld”返回“hello wrld”和“hello world”)。当设置为0时,仅返回成功模糊匹配的单词(例如,“hello wrld”仅返回“hello world”)。对于保留可能在Manticore Search中不存在的短单词或专有名词特别有用。layouts:用于检测键盘布局不匹配导致的打字错误的键盘布局(例如,使用错误布局时输入“ghbdtn”而不是“привет”)。Manticore会比较不同布局中的字符位置以建议更正。要有效检测不匹配,至少需要2种布局。默认情况下不使用任何布局。使用空字符串''(SQL)或数组[](JSON)来关闭此功能。支持的布局包括:be- 比利时AZERTY布局bg- 标准保加利亚布局br- 巴西QWERTY布局ch- 瑞士QWERTZ布局de- 德国QWERTZ布局dk- 丹麦QWERTY布局es- 西班牙QWERTY布局fr- 法国AZERTY布局uk- 英国QWERTY布局gr- 希腊QWERTY布局it- 意大利QWERTY布局no- 挪威QWERTY布局pt- 葡萄牙QWERTY布局ru- 俄语JCUKEN布局se- 瑞典QWERTY布局ua- 乌克兰JCUKEN布局us- 美国QWERTY布局
- 此演示 展示了模糊搜索功能:

- 关于模糊搜索和自动补全的博客文章 - https://manticoresearch.com/blog/new-fuzzy-search-and-autocomplete/
这两个命令都可以通过 SQL 访问,并支持查询本地(普通和实时)和分布式表。语法如下:
CALL QSUGGEST(<word or words>, <table name> [,options])
CALL SUGGEST(<word or words>, <table name> [,options])
options: N as option_name[, M as another_option, ...]
这些命令为给定单词提供字典中的所有建议。它们仅在启用了 前缀匹配 并且 dict=keywords 的表上工作。它们返回建议的关键词、建议关键词与原始关键词之间的莱文斯坦距离,以及建议关键词的文档统计信息。
如果第一个参数包含多个单词,则:
CALL QSUGGEST将仅返回 最后一个 单词的建议,忽略其余部分。CALL SUGGEST将仅返回 第一个 单词的建议。
这是它们之间唯一的区别。支持以下选项进行自定义:
| 选项 | 描述 | 默认 |
|---|---|---|
| limit | 返回 N 个最佳匹配 | 5 |
| max_edits | 仅保留与原始关键词的莱文斯坦距离小于或等于 N 的字典单词 | 4 |
| result_stats | 提供找到的单词的莱文斯坦距离和文档数量 | 1(启用) |
| delta_len | 仅保留与原始单词长度差异小于 N 的字典单词 | 3 |
| max_matches | 保留的匹配数 | 25 |
| reject | 被拒绝的单词是那些不如匹配队列中已有单词的匹配项。它们被放入一个被拒绝队列中,如果其中一个实际上可以进入匹配队列,该队列会被重置。此参数定义了被拒绝队列的大小(作为 reject*max(max_matched,limit))。如果被拒绝队列已满,引擎将停止寻找潜在匹配 | 4 |
| result_line | 通过返回所有建议、距离和文档每行显示数据的替代模式 | 0 |
| non_char | 不跳过包含非字母符号的字典单词 | 0(跳过此类单词) |
| sentence | 返回原始句子,同时将最后一个单词替换为匹配项 | 0(不返回完整句子) |
| force_bigrams | 强制使用二元组(2字符 n-gram)而不是三元组来处理所有单词长度,这可以改善具有换位错误的单词的匹配 | 0(对长度≥6的单词使用三元组) |
| search_mode | 通过在索引上执行搜索来细化建议。接受 'phrase' 用于精确短语匹配或 'words' 用于词袋匹配。启用时,添加一个 found_docs 列显示文档数量,并按 found_docs 降序、然后按 distance 升序重新排序结果 |
N/A(默认禁用) |
为了展示其工作方式,让我们创建一个表并向其中添加几个文档。
create table products(title text) min_infix_len='2';
insert into products values (0,'Crossbody Bag with Tassel'), (0,'microfiber sheet set'), (0,'Pet Hair Remover Glove');
如您所见,拼写错误的单词 "crossbUdy" 会被更正为 "crossbody"。默认情况下,CALL SUGGEST/QSUGGEST 返回:
distance- 莱文斯坦距离,表示将给定单词转换为建议所需进行的编辑次数docs- 包含建议单词的文档数量
要禁用这些统计信息的显示,可以使用选项 0 as result_stats。
- Example
call suggest('crossbudy', 'products');+-----------+----------+------+
| suggest | distance | docs |
+-----------+----------+------+
| crossbody | 1 | 1 |
+-----------+----------+------+- Example
call suggest('bagg with tasel', 'products');+---------+----------+------+
| suggest | distance | docs |
+---------+----------+------+
| bag | 1 | 1 |
+---------+----------+------+- Example
CALL QSUGGEST('bagg with tasel', 'products');+---------+----------+------+
| suggest | distance | docs |
+---------+----------+------+
| tassel | 1 | 1 |
+---------+----------+------+添加 1 as sentence 会使 CALL QSUGGEST 返回整个句子,其中最后一个单词被更正。
- Example
CALL QSUGGEST('bag with tasel', 'products', 1 as sentence);+-------------------+----------+------+
| suggest | distance | docs |
+-------------------+----------+------+
| bag with tassel | 1 | 1 |
+-------------------+----------+------+1 as result_line 选项会改变建议在输出中的显示方式。与其在单独的行中显示每个建议,它会在单行中显示所有建议、距离和文档。以下是一个示例来演示这一点:
CALL QSUGGEST('bagg with tasel', 'products', 1 as result_line);
+----------+--------+
| name | value |
+----------+--------+
| suggests | tassel |
| distance | 1 |
| docs | 1 |
+----------+--------+
force_bigrams 选项可以帮助处理具有换位错误的单词,例如 "ipohne" 与 "iphone"。通过使用二元组而不是三元组,算法可以更好地处理字符换位。
CALL SUGGEST('ipohne', 'products', 1 as force_bigrams);
+--------+----------+------+
| suggest| distance | docs |
+--------+----------+------+
| iphone | 2 | 1 |
+--------+----------+------+
search_mode 选项通过在索引上执行实际搜索来增强建议,以计算每个建议短语或单词组合包含多少文档。这有助于根据实际文档的相关性而不是仅字典统计信息对建议进行排序。
该选项接受两个值:
'phrase'- 执行精确短语搜索。例如,当建议“带流苏的包”时,它会搜索精确短语"bag with tassel"并统计包含这些词作为相邻短语的文档数量。'words'- 执行词袋搜索。例如,当建议“带流苏的包”时,它会搜索bag with tassel(不带引号),并统计包含所有这些词的文档数量,无论顺序或中间是否有其他词。
注意:当
sentence被启用时(即输入包含多个词时),search_mode选项才起作用。对于单词查询,search_mode被忽略。
注意:性能考虑:每个建议候选都会触发一次独立的搜索查询。如果您需要评估许多候选,请考虑使用较低的
limit值以减少执行的搜索次数。
当启用 search_mode 时,结果会包含一个 found_docs 列,显示每个建议的文档数量,并按 found_docs 降序重新排序,然后按 distance 升序排序。
CALL QSUGGEST('bag with tasel', 'products', 1 as sentence, 'phrase' as search_mode);
+-------------------+----------+------+-------------+
| suggest | distance | docs | found_docs |
+-------------------+----------+------+-------------+
| bag with tassel | 1 | 13 | 10 |
| bag with tazer | 2 | 27 | 3 |
+-------------------+----------+------+-------------+
-- With phrase matching: finds exact phrases only
CALL QSUGGEST('test carp', 'products', 1 as sentence, 'phrase' as search_mode);
-- With words matching: finds documents with all words regardless of order
CALL QSUGGEST('test carp', 'products', 1 as sentence, 'words' as search_mode);
-- Phrase mode results:
+----------------+----------+------+-------------+
| suggest | distance | docs | found_docs |
+----------------+----------+------+-------------+
| test car | 1 | 17 | 5 |
| test carpet | 2 | 19 | 4 |
+----------------+----------+------+-------------+
-- Words mode results (more matches for "test carpet" due to word separation):
+----------------+----------+------+-------------+
| suggest | distance | docs | found_docs |
+----------------+----------+------+-------------+
| test carpet | 2 | 19 | 19 |
| test car | 1 | 17 | 5 |
+----------------+----------+------+-------------+
理解差异:
- 短语匹配 (
'phrase'):搜索精确序列。查询"test carpet"仅匹配包含这些词按此精确顺序出现的文档(例如,“test carpet cleaning”匹配,但“test the carpet”或“carpet test”不匹配)。 - 词袋匹配 (
'words'):搜索文档中包含所有词,顺序无关。查询test carpet匹配任何包含“test”和“carpet”的文档(例如,“test the carpet”、“test red carpet”、“carpet test”均匹配)。
- 这个交互式课程 展示了
CALL SUGGEST在小型网络应用中的工作方式。

拼写校正,也称为:
- 自动更正
- 文本校正
- 修正拼写错误
- 键入容错
- “您是否是指?”
等等,是一种软件功能,可以建议或自动更正您输入的文本的替代方案。校正输入文本的概念可以追溯到1960年代,当时计算机科学家Warren Teitelman(也是“撤销”命令的发明者)引入了一种称为D.W.I.M.(“Do What I Mean”,即“按我的意图执行”)的计算哲学。Teitelman认为,计算机不应该仅被编程为接受格式完美的指令,而应该被编程为识别明显的错误。
第一个提供拼写校正功能的知名产品是1993年发布的Microsoft Word 6.0。
拼写校正可以通过几种方式实现,但需要注意的是,没有纯粹的程序化方法可以将您误输入的“ipone”高质量地转换为“iphone”。大多数情况下,系统必须基于某个数据集。数据集可以是:
- 一个正确拼写的单词字典,该字典可以是:
- 基于您的真实数据。这里的思路是,字典中大部分拼写是正确的,系统会尝试找到与输入单词最相似的单词(我们稍后将讨论如何使用Manticore实现这一点)。
- 或者基于与您的数据无关的外部字典。这里可能出现的问题是,您的数据和外部字典可能差异太大:字典中可能缺少一些单词,而您的数据中可能缺少其他单词。
- 不仅基于字典,还具备上下文感知能力,例如“white ber”会被校正为“white bear”,而“dark ber”会被校正为“dark beer”。上下文可能不仅仅是查询中的相邻单词,还可能包括您的位置、时间、当前句子的语法(例如是否将“there”更正为“their”)、您的搜索历史,以及几乎所有可能影响您意图的其他因素。
- 另一种经典方法是使用之前的搜索查询作为拼写校正的数据集。这在自动补全功能中被更广泛地使用,但对自动更正也适用。其思路是,用户在拼写上大多是正确的,因此我们可以使用他们搜索历史中的单词作为事实来源,即使我们没有在文档中使用这些单词或使用外部字典。此处也可以实现上下文感知。
Manticore提供了模糊搜索选项以及可用于自动拼写校正的命令CALL QSUGGEST和CALL SUGGEST。
模糊搜索功能通过考虑搜索查询中的细微变化或拼写错误,允许更灵活的匹配。它的工作方式类似于普通的SELECT SQL语句或/search JSON请求,但提供了额外的参数来控制模糊匹配行为。
注意:
fuzzy选项需要Manticore Buddy。如果不起作用,请确保已安装Buddy。
注意:
fuzzy选项不适用于多查询。
SELECT
...
MATCH('...')
...
OPTION fuzzy={0|1}
[, distance=N]
[, preserve={0|1}]
[, layouts='{be,bg,br,ch,de,dk,es,fr,uk,gr,it,no,pt,ru,se,ua,us}']
}
注意:通过SQL进行模糊搜索时,MATCH子句不应包含任何全文本运算符,除了短语搜索运算符,并且应仅包含您打算匹配的单词。
- SQL
- SQL with additional filters
- JSON
- SQL with preserve option
- JSON with preserve option
SELECT * FROM mytable WHERE MATCH('someting') OPTION fuzzy=1, layouts='us,ua', distance=2;带有附加筛选器的更复杂模糊搜索查询示例:
SELECT * FROM mytable WHERE MATCH('someting') OPTION fuzzy=1 AND (category='books' AND price < 20);POST /search
{
"table": "test",
"query": {
"bool": {
"must": [
{
"match": {
"*": "ghbdtn"
}
}
]
}
},
"options": {
"fuzzy": true,
"layouts": ["us", "ru"],
"distance": 2
}
}SELECT * FROM mytable WHERE MATCH('hello wrld') OPTION fuzzy=1, preserve=1;POST /search
{
"table": "test",
"query": {
"bool": {
"must": [
{
"match": {
"*": "hello wrld"
}
}
]
}
},
"options": {
"fuzzy": true,
"preserve": 1
}
}+------+-------------+
| id | content |
+------+-------------+
| 1 | something |
| 2 | some thing |
+------+-------------+
2 rows in set (0.00 sec)+------+-------------+
| id | content |
+------+-------------+
| 1 | hello wrld |
| 2 | hello world |
+------+-------------+
2 rows in set (0.00 sec)POST /search
{
"table": "table_name",
"query": {
<full-text query>
},
"options": {
"fuzzy": {true|false}
[,"layouts": ["be","bg","br","ch","de","dk","es","fr","uk","gr","it","no","pt","ru","se","ua","us"]]
[,"distance": N]
[,"preserve": {0|1}]
}
}
注意:如果您使用query_string,请注意它不支持除短语搜索运算符以外的全文本运算符。查询字符串应仅包含您希望匹配的单词。
fuzzy:启用或关闭模糊搜索。distance:设置匹配的莱文斯坦距离。默认值为2。preserve:0或1(默认:0)。当设置为1时,在搜索结果中保留没有模糊匹配的单词(例如,“hello wrld”返回“hello wrld”和“hello world”)。当设置为0时,仅返回成功模糊匹配的单词(例如,“hello wrld”仅返回“hello world”)。对于保留可能在Manticore Search中不存在的短单词或专有名词特别有用。layouts:用于检测键盘布局不匹配导致的打字错误的键盘布局(例如,使用错误布局时输入“ghbdtn”而不是“привет”)。Manticore会比较不同布局中的字符位置以建议更正。要有效检测不匹配,至少需要2种布局。默认情况下不使用任何布局。使用空字符串''(SQL)或数组[](JSON)来关闭此功能。支持的布局包括:be- 比利时AZERTY布局bg- 标准保加利亚布局br- 巴西QWERTY布局ch- 瑞士QWERTZ布局de- 德国QWERTZ布局dk- 丹麦QWERTY布局es- 西班牙QWERTY布局fr- 法国AZERTY布局uk- 英国QWERTY布局gr- 希腊QWERTY布局it- 意大利QWERTY布局no- 挪威QWERTY布局pt- 葡萄牙QWERTY布局ru- 俄语JCUKEN布局se- 瑞典QWERTY布局ua- 乌克兰JCUKEN布局us- 美国QWERTY布局
- 此演示 展示了模糊搜索功能:

- 关于模糊搜索和自动补全的博客文章 - https://manticoresearch.com/blog/new-fuzzy-search-and-autocomplete/
这两个命令都可以通过 SQL 访问,并支持查询本地(普通和实时)和分布式表。语法如下:
CALL QSUGGEST(<word or words>, <table name> [,options])
CALL SUGGEST(<word or words>, <table name> [,options])
options: N as option_name[, M as another_option, ...]
这些命令为给定单词提供字典中的所有建议。它们仅在启用了 前缀匹配 并且 dict=keywords 的表上工作。它们返回建议的关键词、建议关键词与原始关键词之间的莱文斯坦距离,以及建议关键词的文档统计信息。
如果第一个参数包含多个单词,则:
CALL QSUGGEST将仅返回 最后一个 单词的建议,忽略其余部分。CALL SUGGEST将仅返回 第一个 单词的建议。
这是它们之间唯一的区别。支持以下选项进行自定义:
| 选项 | 描述 | 默认 |
|---|---|---|
| limit | 返回 N 个最佳匹配 | 5 |
| max_edits | 仅保留与原始关键词的莱文斯坦距离小于或等于 N 的字典单词 | 4 |
| result_stats | 提供找到的单词的莱文斯坦距离和文档数量 | 1(启用) |
| delta_len | 仅保留与原始单词长度差异小于 N 的字典单词 | 3 |
| max_matches | 保留的匹配数 | 25 |
| reject | 被拒绝的单词是那些不如匹配队列中已有单词的匹配项。它们被放入一个被拒绝队列中,如果其中一个实际上可以进入匹配队列,该队列会被重置。此参数定义了被拒绝队列的大小(作为 reject*max(max_matched,limit))。如果被拒绝队列已满,引擎将停止寻找潜在匹配 | 4 |
| result_line | 通过返回所有建议、距离和文档每行显示数据的替代模式 | 0 |
| non_char | 不跳过包含非字母符号的字典单词 | 0(跳过此类单词) |
| sentence | 返回原始句子,同时将最后一个单词替换为匹配项 | 0(不返回完整句子) |
| force_bigrams | 强制使用二元组(2字符 n-gram)而不是三元组来处理所有单词长度,这可以改善具有换位错误的单词的匹配 | 0(对长度≥6的单词使用三元组) |
| search_mode | 通过在索引上执行搜索来细化建议。接受 'phrase' 用于精确短语匹配或 'words' 用于词袋匹配。启用时,添加一个 found_docs 列显示文档数量,并按 found_docs 降序、然后按 distance 升序重新排序结果 |
N/A(默认禁用) |
为了展示其工作方式,让我们创建一个表并向其中添加几个文档。
create table products(title text) min_infix_len='2';
insert into products values (0,'Crossbody Bag with Tassel'), (0,'microfiber sheet set'), (0,'Pet Hair Remover Glove');
如您所见,拼写错误的单词 "crossbUdy" 会被更正为 "crossbody"。默认情况下,CALL SUGGEST/QSUGGEST 返回:
distance- 莱文斯坦距离,表示将给定单词转换为建议所需进行的编辑次数docs- 包含建议单词的文档数量
要禁用这些统计信息的显示,可以使用选项 0 as result_stats。
- Example
call suggest('crossbudy', 'products');+-----------+----------+------+
| suggest | distance | docs |
+-----------+----------+------+
| crossbody | 1 | 1 |
+-----------+----------+------+- Example
call suggest('bagg with tasel', 'products');+---------+----------+------+
| suggest | distance | docs |
+---------+----------+------+
| bag | 1 | 1 |
+---------+----------+------+- Example
CALL QSUGGEST('bagg with tasel', 'products');+---------+----------+------+
| suggest | distance | docs |
+---------+----------+------+
| tassel | 1 | 1 |
+---------+----------+------+添加 1 as sentence 会使 CALL QSUGGEST 返回整个句子,其中最后一个单词被更正。
- Example
CALL QSUGGEST('bag with tasel', 'products', 1 as sentence);+-------------------+----------+------+
| suggest | distance | docs |
+-------------------+----------+------+
| bag with tassel | 1 | 1 |
+-------------------+----------+------+1 as result_line 选项会改变建议在输出中的显示方式。与其在单独的行中显示每个建议,它会在单行中显示所有建议、距离和文档。以下是一个示例来演示这一点:
CALL QSUGGEST('bagg with tasel', 'products', 1 as result_line);
+----------+--------+
| name | value |
+----------+--------+
| suggests | tassel |
| distance | 1 |
| docs | 1 |
+----------+--------+
force_bigrams 选项可以帮助处理具有换位错误的单词,例如 "ipohne" 与 "iphone"。通过使用二元组而不是三元组,算法可以更好地处理字符换位。
CALL SUGGEST('ipohne', 'products', 1 as force_bigrams);
+--------+----------+------+
| suggest| distance | docs |
+--------+----------+------+
| iphone | 2 | 1 |
+--------+----------+------+
search_mode 选项通过在索引上执行实际搜索来增强建议,以计算每个建议短语或单词组合包含多少文档。这有助于根据实际文档的相关性而不是仅字典统计信息对建议进行排序。
该选项接受两个值:
'phrase'- 执行精确短语搜索。例如,当建议“带流苏的包”时,它会搜索精确短语"bag with tassel"并统计包含这些词作为相邻短语的文档数量。'words'- 执行词袋搜索。例如,当建议“带流苏的包”时,它会搜索bag with tassel(不带引号),并统计包含所有这些词的文档数量,无论顺序或中间是否有其他词。
注意:当
sentence被启用时(即输入包含多个词时),search_mode选项才起作用。对于单词查询,search_mode被忽略。
注意:性能考虑:每个建议候选都会触发一次独立的搜索查询。如果您需要评估许多候选,请考虑使用较低的
limit值以减少执行的搜索次数。
当启用 search_mode 时,结果会包含一个 found_docs 列,显示每个建议的文档数量,并按 found_docs 降序重新排序,然后按 distance 升序排序。
CALL QSUGGEST('bag with tasel', 'products', 1 as sentence, 'phrase' as search_mode);
+-------------------+----------+------+-------------+
| suggest | distance | docs | found_docs |
+-------------------+----------+------+-------------+
| bag with tassel | 1 | 13 | 10 |
| bag with tazer | 2 | 27 | 3 |
+-------------------+----------+------+-------------+
-- With phrase matching: finds exact phrases only
CALL QSUGGEST('test carp', 'products', 1 as sentence, 'phrase' as search_mode);
-- With words matching: finds documents with all words regardless of order
CALL QSUGGEST('test carp', 'products', 1 as sentence, 'words' as search_mode);
-- Phrase mode results:
+----------------+----------+------+-------------+
| suggest | distance | docs | found_docs |
+----------------+----------+------+-------------+
| test car | 1 | 17 | 5 |
| test carpet | 2 | 19 | 4 |
+----------------+----------+------+-------------+
-- Words mode results (more matches for "test carpet" due to word separation):
+----------------+----------+------+-------------+
| suggest | distance | docs | found_docs |
+----------------+----------+------+-------------+
| test carpet | 2 | 19 | 19 |
| test car | 1 | 17 | 5 |
+----------------+----------+------+-------------+
理解差异:
- 短语匹配 (
'phrase'):搜索精确序列。查询"test carpet"仅匹配包含这些词按此精确顺序出现的文档(例如,“test carpet cleaning”匹配,但“test the carpet”或“carpet test”不匹配)。 - 词袋匹配 (
'words'):搜索文档中包含所有词,顺序无关。查询test carpet匹配任何包含“test”和“carpet”的文档(例如,“test the carpet”、“test red carpet”、“carpet test”均匹配)。
- 这个交互式课程 展示了
CALL SUGGEST在小型网络应用中的工作方式。

查询缓存将压缩的结果集存储在内存中,并在可能时对后续查询重用它们。您可以使用以下指令进行配置:
- qcache_max_bytes,缓存查询存储的内存使用限制。默认值为16 MB。将
qcache_max_bytes设置为0会完全禁用查询缓存。 - qcache_thresh_msec,缓存的最小查询耗时阈值。查询完成时间快于该值的将不被缓存。默认值为3000毫秒,即3秒。
- qcache_ttl_sec,缓存条目的TTL,即存活时间。查询将在此时间内保持缓存。默认值为60秒,即1分钟。
这些设置可以使用SET GLOBAL语句动态更改:
mysql> SET GLOBAL qcache_max_bytes=128000000;
这些更改会立即生效,不再满足约束的缓存结果集会被立即丢弃。当动态缩减缓存大小时,最近最常用(MRU)的结果集优先保留。
查询缓存的工作方式如下。启用时,每个全文搜索结果将完整存储于内存中。这发生在全文匹配、过滤和排名之后,因此本质上我们存储的是total_found个{docid,weight}对。压缩匹配平均每个匹配耗用2到12字节不等,主要取决于连续docid之间的差异。查询完成后,我们检查耗时和大小阈值,要么保存压缩后的结果集以供重用,要么丢弃它。
请注意,查询缓存对内存的影响不限于qcache_max_bytes!例如,如果您运行10个并发查询,每个查询匹配最多100万条结果(经过过滤后),那么峰值临时内存使用可能在40 MB到240 MB之间,即使查询够快且未被缓存。
当表、全文查询(即MATCH()内容)和排序器都匹配,且过滤条件兼容时,查询可以使用缓存。具体而言:
MATCH()中的全文部分必须逐字节匹配。添加一个额外的空格,在查询缓存看来就是一个不同的查询。- 排序器(及其参数,如自定义排序器的参数)必须逐字节匹配。
- 过滤条件必须是原过滤条件的超集。您可以添加额外过滤条件仍然命中缓存。(在这种情况下,额外过滤条件将在缓存结果上应用。)但如果移除一个过滤条件,则视为新的查询。
缓存条目会按TTL过期,并在表轮换、TRUNCATE或ATTACH时失效。请注意,目前条目不会因任意RT表写入而失效!因此缓存的查询可能在TTL期间返回较旧的结果。
您可以通过SHOW STATUS 使用qcache_XXX变量查看当前缓存状态:
mysql> SHOW STATUS LIKE 'qcache%';
+-----------------------+----------+
| Counter | Value |
+-----------------------+----------+
| qcache_max_bytes | 16777216 |
| qcache_thresh_msec | 3000 |
| qcache_ttl_sec | 60 |
| qcache_cached_queries | 0 |
| qcache_used_bytes | 0 |
| qcache_hits | 0 |
+-----------------------+----------+
6 rows in set (0.00 sec)
排序规则主要影响字符串属性的比较。它们定义了字符集编码以及 Manticore 在执行涉及字符串属性的 ORDER BY 或 GROUP BY 时用于比较字符串的策略。
字符串属性在索引过程中按原样存储,并且不附带字符集或语言信息。只要 Manticore 仅需将字符串逐字存储和返回给调用应用程序,这种方式是可以的。然而,当您要求 Manticore 按字符串值排序时,请求立即变得模糊。
首先,单字节(ASCII、ISO-8859-1 或 Windows-1251)字符串需要与可能用可变字节数编码每个字符的 UTF-8 字符串不同地处理。因此,我们需要知道字符集类型,以便正确地将原始字节解释为有意义的字符。
其次,我们还需要了解语言特定的字符串排序规则。例如,在 en_US 地区设置的美国规则下排序时,带变音符号的字符 ï(带变音符号的小写字母 i)应放在 z 之后的某个位置。但在考虑法语规则和 fr_FR 地区设置时,它应放在 i 和 j 之间。其他规则可能完全忽略重音符号,使得 ï 和 i 可以任意混合。
第三,在某些情况下,我们可能需要区分大小写的排序,而在其他情况下,则需要不区分大小写的排序。
排序规则封装了以下所有内容:字符集、语言规则以及大小写敏感性。Manticore 当前提供四种排序规则:
libc_cilibc_csutf8_general_cibinary
前两种排序规则依赖于几个标准 C 库(libc)调用,因此可以支持系统上安装的任何地区设置。它们分别提供不区分大小写(_ci)和区分大小写(_cs)的比较。默认情况下,它们使用 C 地区设置,实际上退化为逐字节比较。若要更改此设置,需要使用 collation_libc_locale 指令指定其他可用地区设置。系统上可用的地区设置列表通常可通过 locale 命令获得:
$ locale -a
C
en_AG
en_AU.utf8
en_BW.utf8
en_CA.utf8
en_DK.utf8
en_GB.utf8
en_HK.utf8
en_IE.utf8
en_IN
en_NG
en_NZ.utf8
en_PH.utf8
en_SG.utf8
en_US.utf8
en_ZA.utf8
en_ZW.utf8
es_ES
fr_FR
POSIX
ru_RU.utf8
ru_UA.utf8
系统地区设置的具体列表可能有所不同。请查阅操作系统文档以安装所需的额外地区设置。
utf8_general_ci 和 binary 地区设置内置于 Manticore 中。第一种是 UTF-8 数据的通用排序规则(无所谓的语言定制),其行为应类似于 MySQL 中的 utf8_general_ci 排序规则。第二种则是简单的逐字节比较。
排序规则可以通过 SQL 语句 SET collation_connection 按会话覆盖。所有后续 SQL 查询将使用该排序规则。否则,所有查询将使用服务器默认排序规则或 collation_server 配置指令中指定的排序规则。Manticore 当前默认使用 libc_ci 排序规则。
排序规则影响所有字符串属性的比较,包括 ORDER BY 和 GROUP BY 中的比较,因此根据选择的排序规则,返回的结果顺序或分组可能不同。请注意,排序规则不影响全文搜索;对此,请使用 charset_table。