通配符搜索是一种常见的文本搜索类型。在 Manticore 中,它是在字典级别执行的。默认情况下,普通表和 RT 表都使用一种称为 dict 的字典类型。在此模式下,单词按原样存储,因此启用通配符不会影响表的大小。当执行通配符搜索时,会搜索字典以查找通配符单词的所有可能扩展。当扩展的单词提供许多扩展或扩展具有庞大命中列表时,尤其是在通配符添加在单词的开头和结尾的中缀情况下,这种扩展在查询时的计算可能会有问题。为避免此类问题,可以使用 expansion_limit。
min_prefix_len = length
此设置确定要索引和搜索的最小单词前缀长度。默认值为 0,表示不允许前缀。
前缀允许通过 wordstart* 通配符进行通配符搜索。
例如,如果单词 "example" 使用 min_prefix_len=3 进行索引,则可以通过搜索 "exa"、"exam"、"examp"、"exampl" 以及完整单词找到它。
请注意,使用 dict=crc 时,min_prefix_len 会影响全文索引的大小,因为每个单词扩展都会额外存储。
如果满足以下条件,Manticore 可以区分完全匹配的单词和前缀匹配,并将前者排名更高:
- dict=keywords(默认开启)
- index_exact_words=1(默认关闭)
- expand_keywords=1(也默认关闭)
请注意,在 dict=crc 模式或上述任何选项禁用时,无法区分前缀和完整单词,且无法将完全匹配的单词排名更高。
当 minimum infix length 设置为正数时,最小前缀长度始终视为 1。
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) min_prefix_len = '3'POST /cli -d "
CREATE TABLE products(title text, price float) min_prefix_len = '3'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'min_prefix_len' => '3'
]);utilsApi.sql('CREATE TABLE products(title text, price float) min_prefix_len = \'3\'')await utilsApi.sql('CREATE TABLE products(title text, price float) min_prefix_len = \'3\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) min_prefix_len = \'3\'');utilsApi.sql("CREATE TABLE products(title text, price float) min_prefix_len = '3'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) min_prefix_len = '3'", true);utils_api.sql("CREATE TABLE products(title text, price float) min_prefix_len = '3'", Some(true)).await;table products {
min_prefix_len = 3
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}min_infix_len = length
min_infix_len 设置确定要索引和搜索的中缀前缀的最小长度。此设置是可选的,默认值为 0,表示不允许中缀。允许的最小非零值为 2。
启用后,中缀允许使用类似 start*、*end、*middle* 等模式进行通配符搜索。它还允许您禁用过短的通配符,以防它们搜索成本过高。
如果满足以下条件,Manticore 可以区分完全匹配的单词和中缀匹配,并将前者排名更高:
- dict=keywords(默认开启)
- index_exact_words=1(默认关闭)
- expand_keywords=1(也默认关闭)
请注意,在 dict=crc 模式或上述任何选项禁用时,无法区分中缀和完整单词,因此无法将完全匹配的单词排名更高。
中缀通配符搜索的查询时间可能变化很大,取决于子字符串实际扩展到多少关键字。像 *in* 或 *ti* 这样短且频繁的音节可能会扩展到过多关键字,所有这些都需要匹配和处理。因此,为了通常启用子字符串搜索,您可以将 min_infix_len 设置为 2。为了限制过短通配符搜索的影响,您可以将其设置得更高。
中缀必须至少有 2 个字符长,出于性能原因,不允许使用像 *a* 这样的通配符。
当 min_infix_len 设置为正数时,最小前缀长度 被视为 1。对于 dict,单词中缀和前缀不能同时启用。对于 dict 和其他字段,如果使用了 prefix_fields 声明了前缀,则禁止在两个列表中声明相同字段。
如果 dict=keywords,除了通配符 * 外,还可以使用另外两个通配符字符:
?可以匹配任意(一个)字符:t?st将匹配test,但不匹配teast%可以匹配零个或一个字符:tes%将匹配tes或test,但不匹配testing
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) min_infix_len = '3'POST /cli -d "
CREATE TABLE products(title text, price float) min_infix_len = '3'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'min_infix_len' => '3'
]);utilsApi.sql('CREATE TABLE products(title text, price float) min_infix_len = \'3\'')await utilsApi.sql('CREATE TABLE products(title text, price float) min_infix_len = \'3\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) min_infix_len = \'3\'');utilsApi.sql("CREATE TABLE products(title text, price float) min_infix_len = '3'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) min_infix_len = '3'", true);utils_api.sql("CREATE TABLE products(title text, price float) min_infix_len = '3'", Some(true)).await;table products {
min_infix_len = 3
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}prefix_fields = field1[, field2, ...]
prefix_fields 设置用于限制前缀索引仅应用于 dict=crc 模式下的特定全文字段。默认情况下,所有字段都会以前缀模式进行索引,但由于前缀索引可能影响索引和搜索性能,因此可能希望将其限制在某些字段上。
要将前缀索引限制为特定字段,请使用 prefix_fields 设置,后跟以逗号分隔的字段名称列表。如果未设置 prefix_fields,则所有字段都将在前缀模式下进行索引。
- CONFIG
table products {
prefix_fields = title, name
min_prefix_len = 3
dict = crcinfix_fields = field1[, field2, ...]
infix_fields 设置允许您指定一个全文字段列表,以限制中缀索引的应用范围。这仅适用于 dict=crc 模式,且是可选的,默认情况下所有字段都以中缀模式进行索引。 此设置类似于 prefix_fields,但它允许您将中缀索引限制在特定字段上。
- CONFIG
table products {
infix_fields = title, name
min_infix_len = 3
dict = crcmax_substring_len = length
max_substring_len 指令设置要为前缀或中缀搜索索引的最大子字符串长度。此设置是可选的,默认值为 0(表示索引所有可能的子字符串)。它仅适用于 dict。
默认情况下,dict 中的子字符串索引会将 所有 可能的子字符串作为单独的关键字进行索引,这可能导致全文索引过大。因此,max_substring_len 指令允许您跳过过长且可能永远不会被搜索的子字符串。
例如,一个包含 10,000 篇博客文章的测试表根据设置占用不同的磁盘空间:
- 6.4 MB 基线(无子字符串)
- 24.3 MB(3.8 倍)使用 min_prefix_len = 3
- 22.2 MB(3.5 倍)使用 min_prefix_len = 3,max_substring_len = 8
- 19.3 MB(3.0 倍)使用 min_prefix_len = 3,max_substring_len = 6
- 94.3 MB(14.7 倍)使用 min_infix_len = 3
- 84.6 MB(13.2 倍)使用 min_infix_len = 3,max_substring_len = 8
- 70.7 MB(11.0 倍)使用 min_infix_len = 3,max_substring_len = 6
因此,限制最大子字符串长度可以节省 10-15% 的表大小。
在使用 dict=keywords 模式时,子字符串长度不会影响性能。因此,该指令不适用且在这种情况下被故意禁止。不过,如果需要,您仍然可以在应用代码中限制搜索子字符串的长度。
- CONFIG
table products {
max_substring_len = 12
min_infix_len = 3
dict = crcexpand_keywords = {0|1|exact|star}
此设置在可能的情况下扩展关键字为其精确形式和/或带星号的形式。支持的值有:
- 1 - 同时扩展为精确形式和带星号的形式。例如,
running将变为(running | *running* | =running) exact- 仅用其精确形式扩展关键字。例如,running将变为(running | =running)star- 通过在关键字周围添加*来扩展关键字。例如,running将变为(running | *running*)此设置是可选的,默认值为 0(不扩展关键字)。
启用 expand_keywords 功能的表的查询会在内部进行如下扩展:如果表启用了前缀或中缀索引,则每个关键字都会被内部替换为关键字本身与相应的前缀或中缀(带星号的关键字)的析取。如果表同时启用了词干提取和 index_exact_words,还会添加精确形式。
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) expand_keywords = '1'POST /cli -d "
CREATE TABLE products(title text, price float) expand_keywords = '1'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'expand_keywords' => '1'
]);utilsApi.sql('CREATE TABLE products(title text, price float) expand_keywords = \'1\'')await utilsApi.sql('CREATE TABLE products(title text, price float) expand_keywords = \'1\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) expand_keywords = \'1\'');utilsApi.sql("CREATE TABLE products(title text, price float) expand_keywords = '1'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) expand_keywords = '1'", true);utils_api.sql("CREATE TABLE products(title text, price float) expand_keywords = '1'", Some(true)).await;table products {
expand_keywords = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}扩展后的查询自然需要更长时间完成,但可能提升搜索质量,因为精确形式匹配的文档通常应比词干或中缀匹配的文档排名更高。
注意,现有的查询语法不允许模拟这种扩展,因为内部扩展是在关键字级别进行的,并且会扩展短语或仲裁操作符内的关键字(这是查询语法无法实现的)。请查看示例,了解 expand_keywords 如何影响搜索结果权重,以及如何在不添加星号的情况下通过 "runs" 找到 "runsy":
- expand_keywords_enabled
- expand_keywords_disabled
mysql> create table t(f text) min_infix_len='2' expand_keywords='1' morphology='stem_en';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> insert into t values(1,'running'),(2,'runs'),(3,'runsy');
Query OK, 3 rows affected (0.00 sec)
mysql> select *, weight() from t where match('runs');
+------+---------+----------+
| id | f | weight() |
+------+---------+----------+
| 2 | runs | 1560 |
| 1 | running | 1500 |
| 3 | runsy | 1500 |
+------+---------+----------+
3 rows in set (0.01 sec)
mysql> drop table t;
Query OK, 0 rows affected (0.01 sec)
mysql> create table t(f text) min_infix_len='2' expand_keywords='exact' morphology='stem_en';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> insert into t values(1,'running'),(2,'runs'),(3,'runsy');
Query OK, 3 rows affected (0.00 sec)
mysql> select *, weight() from t where match('running');
+------+---------+----------+
| id | f | weight() |
+------+---------+----------+
| 1 | running | 1590 |
| 2 | runs | 1500 |
+------+---------+----------+
2 rows in set (0.00 sec)mysql> create table t(f text) min_infix_len='2' morphology='stem_en';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> insert into t values(1,'running'),(2,'runs'),(3,'runsy');
Query OK, 3 rows affected (0.00 sec)
mysql> select *, weight() from t where match('runs');
+------+---------+----------+
| id | f | weight() |
+------+---------+----------+
| 1 | running | 1500 |
| 2 | runs | 1500 |
+------+---------+----------+
2 rows in set (0.00 sec)
mysql> drop table t;
Query OK, 0 rows affected (0.01 sec)
mysql> create table t(f text) min_infix_len='2' morphology='stem_en';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> insert into t values(1,'running'),(2,'runs'),(3,'runsy');
Query OK, 3 rows affected (0.00 sec)
mysql> select *, weight() from t where match('running');
+------+---------+----------+
| id | f | weight() |
+------+---------+----------+
| 1 | running | 1500 |
| 2 | runs | 1500 |
+------+---------+----------+
2 rows in set (0.00 sec)该指令不会以任何方式影响indexer,它只影响searchd。
expansion_limit = number
单个通配符的最大扩展关键字数。详细信息见这里。
停用词是在索引和搜索过程中被忽略的词,通常由于其高频率且对搜索结果价值较低。
Manticore Search 默认对停用词应用词干提取,这可能导致不理想的结果,但可以通过使用stopwords_unstemmed来关闭此功能。
小型停用词文件存储在表头中,嵌入文件的大小有限制,该限制由embedded_limit选项定义。
停用词不被索引,但会影响关键词的位置。例如,如果“the”是停用词,文档1包含短语“in office”,而文档2包含短语“in the office”,搜索“in office”作为精确短语时只会返回第一个文档,尽管第二个文档中的“the”作为停用词被跳过。此行为可以通过stopword_step指令进行修改。
stopwords=path/to/stopwords/file[ path/to/another/file ...]
stopwords 设置是可选的,默认为空。它允许你指定一个或多个停用词文件的路径,路径之间用空格分隔。所有文件都会被加载。在实时模式下,只允许使用绝对路径。
停用词文件格式为简单的 UTF-8 编码纯文本。文件数据将根据charset_table设置进行分词,因此你可以使用与索引数据相同的分隔符。
停用词文件可以手动或半自动创建。indexer 提供了一个模式,可以创建按关键词频率排序的表频率字典。该字典中的热门关键词通常可以用作停用词。详情请参见--buildstops和--buildfreqs开关。该字典中的热门关键词通常可以用作停用词。
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) stopwords = '/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt'POST /cli -d "
CREATE TABLE products(title text, price float) stopwords = '/usr/local/manticore/data/stopwords.txt stopwords-ru.txt stopwords-en.txt'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'stopwords' => '/usr/local/manticore/data/stopwords.txt stopwords-ru.txt stopwords-en.txt'
]);utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt\'')await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt\'');utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = '/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) stopwords = '/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt'", true);utils_api.sql("CREATE TABLE products(title text, price float) stopwords = '/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt'", Some(true)).await;table products {
stopwords = /usr/local/manticore/data/stopwords.txt
stopwords = stopwords-ru.txt stopwords-en.txt
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}或者你可以使用 Manticore 自带的默认停用词文件。目前提供了50种语言的停用词。以下是它们的完整别名列表:
- af - 南非荷兰语
- ar - 阿拉伯语
- bg - 保加利亚语
- bn - 孟加拉语
- ca - 加泰罗尼亚语
- ckb- 库尔德语
- cz - 捷克语
- da - 丹麦语
- de - 德语
- el - 希腊语
- en - 英语
- eo - 世界语
- es - 西班牙语
- et - 爱沙尼亚语
- eu - 巴斯克语
- fa - 波斯语
- fi - 芬兰语
- fr - 法语
- ga - 爱尔兰语
- gl - 加利西亚语
- hi - 印地语
- he - 希伯来语
- hr - 克罗地亚语
- hu - 匈牙利语
- hy - 亚美尼亚语
- id - 印度尼西亚语
- it - 意大利语
- ja - 日语
- ko - 韩语
- la - 拉丁语
- lt - 立陶宛语
- lv - 拉脱维亚语
- mr - 马拉地语
- nl - 荷兰语
- no - 挪威语
- pl - 波兰语
- pt - 葡萄牙语
- ro - 罗马尼亚语
- ru - 俄语
- sk - 斯洛伐克语
- sl - 斯洛文尼亚语
- so - 索马里语
- st - 索托语
- sv - 瑞典语
- sw - 斯瓦希里语
- th - 泰语
- tr - 土耳其语
- yo - 约鲁巴语
- zh - 中文
- zu - 祖鲁语
例如,要使用意大利语的停用词,只需在配置文件中添加以下行:
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) stopwords = 'it'POST /cli -d "
CREATE TABLE products(title text, price float) stopwords = 'it'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'stopwords' => 'it'
]);utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'it\'')await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'it\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'it\'');utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = 'it'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) stopwords = 'it'", true);utils_api.sql("CREATE TABLE products(title text, price float) stopwords = 'it'", Some(true)).await;table products {
stopwords = it
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}如果你需要使用多种语言的停用词,应列出所有别名,RT模式下用逗号分隔,普通模式下用空格分隔:
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) stopwords = 'en, it, ru'POST /cli -d "
CREATE TABLE products(title text, price float) stopwords = 'en, it, ru'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'stopwords' => 'en, it, ru'
]);utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en, it, ru\'')await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en, it, ru\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en, it, ru\'');utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = 'en, it, ru'", true);utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = 'en, it, ru'", true);utils_api.sql("CREATE TABLE products(title text, price float) stopwords = 'en, it, ru'", Some(true)).await;table products {
stopwords = en it ru
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}stopword_step={0|1}
stopwords 的 position_increment 设置是可选的,允许的值为0和1,默认值为1。
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) stopwords = 'en' stopword_step = '1'POST /cli -d "
CREATE TABLE products(title text, price float) stopwords = 'en' stopword_step = '1'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'stopwords' => 'en, it, ru',
'stopword_step' => '1'
]);utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en\' stopword_step = \'1\'')await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en\' stopword_step = \'1\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en\' stopword_step = \'1\'');utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = \'en\' stopword_step = \'1\'", true);utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = \'en\' stopword_step = \'1\'", true);utils_api.sql("CREATE TABLE products(title text, price float) stopwords = \'en\' stopword_step = \'1\'", Some(true)).await;table products {
stopwords = en
stopword_step = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}stopwords_unstemmed={0|1}
Whether to apply stop words before or after stemming. Optional, default is 0 (apply stop word filter after stemming).
By default, stop words are stemmed themselves, and then applied to tokens after stemming (or any other morphology processing). This means that a token is stopped when stem(token) is equal to stem(stopword). This default behavior can lead to unexpected results when a token is erroneously stemmed to a stopped root. For example, "Andes" might get stemmed to "and", so when "and" is a stopword, "Andes" is also skipped.
However, you can change this behavior by enabling the stopwords_unstemmed directive. When this is enabled, stop words are applied before stemming (and therefore to the original word forms), and the tokens are skipped when the token is equal to the stopword.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) stopwords = 'en' stopwords_unstemmed = '1'POST /cli -d "
CREATE TABLE products(title text, price float) stopwords = 'en' stopwords_unstemmed = '1'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'stopwords' => 'en, it, ru',
'stopwords_unstemmed' => '1'
]);utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en\' stopwords_unstemmed = \'1\'')await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en\' stopwords_unstemmed = \'1\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en\' stopwords_unstemmed = \'1\'');utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = \'en\' stopwords_unstemmed = \'1\'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) stopwords = \'en\' stopwords_unstemmed = \'1\'", true);utils_api.sql("CREATE TABLE products(title text, price float) stopwords = \'en\' stopwords_unstemmed = \'1\'", Some(true)).await;table products {
stopwords = en
stopwords_unstemmed = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}词形变化在通过 charset_table 规则对输入文本进行分词后应用。它们本质上允许你用另一个词替换一个词。通常,这用于将不同的词形归一化为单一的标准形式(例如,将所有变体如 "walks"、"walked"、"walking" 规范化为标准形式 "walk")。它也可以用来实现 词干提取 的例外情况,因为词干提取不会应用于词形变化列表中的词。
wordforms = path/to/wordforms.txt
wordforms = path/to/alternateforms.txt
wordforms = path/to/dict*.txt
词形变化字典。可选,默认为空。
词形变化字典用于在索引和搜索过程中规范化输入词。因此,对于 plain table 来说,必须旋转表以应用词形变化文件中的更改。
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) wordforms = '/var/lib/manticore/wordforms.txt' wordforms = '/var/lib/manticore/alternateforms.txt /var/lib/manticore/dict*.txt'POST /cli -d "
CREATE TABLE products(title text, price float) wordforms = '/var/lib/manticore/wordforms.txt' wordforms = '/var/lib/manticore/alternateforms.txt' wordforms = '/var/lib/manticore/dict*.txt'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'wordforms' => [
'/var/lib/manticore/wordforms.txt',
'/var/lib/manticore/alternateforms.txt',
'/var/lib/manticore/dict*.txt'
]
]);utilsApi.sql('CREATE TABLE products(title text, price float) wordforms = \'/var/lib/manticore/wordforms.txt\' wordforms = \'/var/lib/manticore/alternateforms.txt\' wordforms = \'/var/lib/manticore/dict*.txt\'')await utilsApi.sql('CREATE TABLE products(title text, price float) wordforms = \'/var/lib/manticore/wordforms.txt\' wordforms = \'/var/lib/manticore/alternateforms.txt\' wordforms = \'/var/lib/manticore/dict*.txt\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float)wordforms = \'/var/lib/manticore/wordforms.txt\' wordforms = \'/var/lib/manticore/alternateforms.txt\' wordforms = \'/var/lib/manticore/dict*.txt\'');utilsApi.sql("CREATE TABLE products(title text, price float) wordforms = '/var/lib/manticore/wordforms.txt' wordforms = '/var/lib/manticore/alternateforms.txt' wordforms = '/var/lib/manticore/dict*.txt'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) wordforms = '/var/lib/manticore/wordforms.txt' wordforms = '/var/lib/manticore/alternateforms.txt' wordforms = '/var/lib/manticore/dict*.txt'", true);utils_api.sql("CREATE TABLE products(title text, price float) wordforms = '/var/lib/manticore/wordforms.txt' wordforms = '/var/lib/manticore/alternateforms.txt' wordforms = '/var/lib/manticore/dict*.txt'", Some(true)).await;table products {
wordforms = /var/lib/manticore/wordforms.txt
wordforms = /var/lib/manticore/alternateforms.txt
wordforms = /var/lib/manticore/dict*.txt
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}Manticore 中的词形变化支持设计为能够良好处理大型字典。它们对索引速度有适度影响;例如,包含 100 万条目的字典会使全文索引速度降低约 1.5 倍。搜索速度完全不受影响。额外的内存占用大致等于字典文件大小,且字典在多个表之间共享。例如,如果同一个 50 MB 的词形变化文件被指定给 10 个不同的表,额外的 searchd 内存使用大约为 50 MB。
字典文件应为简单的纯文本格式。每行应包含源词形和目标词形,使用 UTF-8 编码,并以“大于号”分隔。加载文件时会应用 charset_table 中的规则。因此,如果你不修改 charset_table,你的词形变化将是不区分大小写的,类似于其他全文索引的数据。以下是文件内容的示例:
- Example
walks > walk
walked > walk
walking > walk有一个捆绑的工具叫做 Spelldump,它可以帮助你创建 Manticore 可读取格式的字典文件。该工具可以读取以 ispell 或 MySpell 格式的源 .dict 和 .aff 字典文件,这些文件随 OpenOffice 一起捆绑提供。
你可以将多个源词映射到一个目标词。该过程作用于分词后的词元,而非源文本,因此空白和标记的差异会被忽略。
你可以使用 => 符号代替 >。也允许注释(以 # 开头)。最后,如果一行以波浪号(~)开头,词形变化将在形态学处理之后应用,而非之前(注意此情况下只支持单个源词和目标词)。
- Example
core 2 duo > c2d
e6600 > c2d
core 2duo => c2d # Some people write '2duo' together...
~run > walk # Along with stem_en morphology enabled replaces 'run', 'running', 'runs' (and any other words that stem to just 'run') to 'walk'如果你需要将 >、= 或 ~ 作为普通字符使用,可以通过在它们前面加反斜杠(\)来转义。> 和 = 都应以此方式转义。示例如下:
- Example
a\> > abc
\>b > bcd
c\=\> => cde
\=\>d => def
\=\>a \> f \> => foo
\~g => bar你可以指定多个目标词元:
- Example
s02e02 > season 2 episode 2
s3 e3 > season 3 episode 3你可以指定多个文件,而不仅仅是一个。可以使用通配符作为模式,所有匹配的文件将按简单升序处理:
在 RT 模式下,只允许使用绝对路径。
如果使用多字节编码页且文件名包含非拉丁字符,结果顺序可能不完全是字母顺序。如果在多个文件中发现相同的词形变化定义,后面的定义将覆盖之前的。
- SQL
- Config
create table tbl1 ... wordforms='/tmp/wf*'
create table tbl2 ... wordforms='/tmp/wf, /tmp/wf2'wordforms=/tmp/wf
wordforms=/tmp/wf2
wordforms=/tmp/wf_new*异常(也称为同义词)允许将一个或多个标记(包括通常会被排除的字符的标记)映射到单个关键词。它们类似于wordforms,因为它们也执行映射,但有一些重要的区别。
与wordforms的区别简要总结如下:
| 异常 | 词形 |
|---|---|
| 区分大小写 | 不区分大小写 |
| 可以使用不在charset_table中的特殊字符 | 完全遵守charset_table |
| 在庞大词典中表现较差 | 设计用于处理数百万条目 |
exceptions = path/to/exceptions.txt
分词异常文件。可选,默认为空。 在RT模式下,只允许使用绝对路径。
预期的文件格式是纯文本,每行一个异常。行格式如下:
map-from-tokens => map-to-token
示例文件:
at & t => at&t
AT&T => AT&T
Standarten Fuehrer => standartenfuhrer
Standarten Fuhrer => standartenfuhrer
MS Windows => ms windows
Microsoft Windows => ms windows
C++ => cplusplus
c++ => cplusplus
C plus plus => cplusplus
\=\>abc\> => abc
这里的所有标记都是区分大小写的,并且不会被charset_table规则处理。因此,以上示例异常文件中,at&t文本将被分词为两个关键词at和t,因为小写字母的原因。另一方面,AT&T将完全匹配并生成单个AT&T关键词。
如果需要将>或=作为普通字符使用,可以通过在它们前面加反斜杠(\)来转义。>和=都应以这种方式转义。
请注意,映射到的关键词:
- 总是被解释为单个词
- 对大小写和空格都敏感
在上述示例中,ms windows查询将不会匹配包含MS Windows文本的文档。该查询将被解释为两个关键词ms和windows的查询。MS Windows的映射是单个关键词ms windows,中间有空格。另一方面,standartenfuhrer将检索包含Standarten Fuhrer或Standarten Fuehrer内容(大小写完全如示例所示),或关键词本身的任何大小写变体的文档,例如staNdarTenfUhreR。(但它不会匹配standarten fuhrer:该文本由于大小写敏感性不匹配任何列出的异常,因此被索引为两个独立的关键词。)
映射来源标记列表中的空白符很重要,但其数量无关紧要。映射来源列表中的任意数量空白符都将匹配索引文档或查询中的任意数量空白符。例如,AT & T映射来源标记将匹配AT & T文本,无论映射来源部分和索引文本中的空格数量如何。因此,这样的文本将被索引为特殊的AT&T关键词,这得益于示例中的第一条目。
异常还允许捕获特殊字符(这些字符是一般charset_table规则的例外;因此得名)。假设你通常不想将+视为有效字符,但仍想能够搜索一些此规则的例外,如C++。上述示例完全满足此需求,完全独立于表中包含哪些字符。
使用plain table时,必须旋转表以合并异常文件的更改。对于实时表,更改只会应用于新文档。
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) exceptions = '/usr/local/manticore/data/exceptions.txt'POST /cli -d "
CREATE TABLE products(title text, price float) exceptions = '/usr/local/manticore/data/exceptions.txt'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'exceptions' => '/usr/local/manticore/data/exceptions.txt'
]);utilsApi.sql('CREATE TABLE products(title text, price float) exceptions = \'/usr/local/manticore/data/exceptions.txt\'')await utilsApi.sql('CREATE TABLE products(title text, price float) exceptions = \'/usr/local/manticore/data/exceptions.txt\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) exceptions = \'/usr/local/manticore/data/exceptions.txt\'');utilsApi.sql("CREATE TABLE products(title text, price float) exceptions = '/usr/local/manticore/data/exceptions.txt'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) exceptions = '/usr/local/manticore/data/exceptions.txt'", true);utils_api.sql("CREATE TABLE products(title text, price float) exceptions = '/usr/local/manticore/data/exceptions.txt'", Some(true)).await;table products {
exceptions = /usr/local/manticore/data/exceptions.txt
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}