当文本在 Manticore 中被索引时,它会被拆分成单词,并进行大小写折叠,以便像 "Abc"、"ABC" 和 "abc" 这样的单词被视为相同的单词。
为了正确执行这些操作,Manticore 必须知道:
- 源文本的编码(应始终为 UTF-8)
- 哪些字符被视为字母,哪些不是
- 哪些字母应折叠为其他字母
您可以使用 charset_table 选项按表配置这些设置。charset_table 指定一个数组,将字母字符映射到它们的大小写折叠版本(或您偏好的其他字符)。数组中未出现的字符被视为非字母,并在该表的索引或搜索过程中作为单词分隔符处理。
默认字符集是 non_cont,它包括大多数语言。
您还可以定义文本模式替换规则。例如,使用以下规则:
regexp_filter = \**(\d+)\" => \1 inch
regexp_filter = (BLUE|RED) => COLOR
文本 RED TUBE 5" LONG 将被索引为 COLOR TUBE 5 INCH LONG,而 PLANK 2" x 4" 将被索引为 PLANK 2 INCH x 4 INCH。这些规则按指定顺序应用。规则也适用于查询,因此搜索 BLUE TUBE 实际上会搜索 COLOR TUBE。
# default
charset_table = non_cont
# only English and Russian letters
charset_table = 0..9, A..Z->a..z, _, a..z, \
U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451
# english charset defined with alias
charset_table = 0..9, english, _
# you can override character mappings by redefining them, e.g. for case insensitive search with German umlauts you can use:
charset_table = non_cont, U+00E4, U+00C4->U+00E4, U+00F6, U+00D6->U+00F6, U+00FC, U+00DC->U+00FC, U+00DF, U+1E9E->U+00DF
charset_table 指定一个数组,将字母字符映射到它们的大小写折叠版本(或您偏好的其他字符)。默认字符集是 non_cont,它包括大多数使用非连续脚本的语言。
charset_table 是 Manticore 分词过程的核心,它从文档文本或查询文本中提取关键词。它控制哪些字符被接受为有效字符以及它们应如何转换(例如是否去除大小写)。
默认情况下,每个字符映射为 0,表示它不被视为有效关键词,且被视为分隔符。一旦字符在表中被提及,它就会被映射到另一个字符(通常是映射到自身或小写字母),并被视为有效的关键词部分。
charset_table 使用逗号分隔的映射列表来声明字符为有效或将它们映射到其他字符。语法快捷方式可用于一次映射一系列字符:
- 单字符映射:
A->a。声明源字符 'A' 在关键词中允许,并映射到目标字符 'a'(但不声明 'a' 为允许字符)。 - 范围映射:
A..Z->a..z。声明源范围内的所有字符为允许,并映射到目标范围。不会声明目标范围为允许。会检查两个范围的长度。 - 单独字符映射:
a。声明字符为允许,并映射到自身。等同于a->a单字符映射。 - 单独范围映射:
a..z。声明范围内所有字符为允许,并映射到自身。等同于a..z->a..z范围映射。 - 棋盘范围映射:
A..Z/2。将每对字符映射到第二个字符。例如,A..Z/2等同于A->B, B->B, C->D, D->D, ..., Y->Z, Z->Z。此映射快捷方式适用于大写和小写字母交错排列的 Unicode 块。
对于代码从 0 到 32 的字符,以及 127 到 8 位 ASCII 和 Unicode 字符范围内的字符,Manticore 总是将它们视为分隔符。为避免配置文件编码问题,8 位 ASCII 字符和 Unicode 字符必须以 U+XXX 形式指定,其中 XXX 是十六进制代码点编号。接受的最小 Unicode 字符代码是 U+0021。
如果默认映射不能满足您的需求,您可以通过再次指定映射来重新定义字符映射。例如,如果内置的 non_cont 数组包含字符 Ä 和 ä 并将它们都映射到 ASCII 字符 a,您可以通过添加它们的 Unicode 代码点来重新定义这些字符,如下所示:
charset_table = non_cont,U+00E4,U+00C4
用于区分大小写的搜索,或
charset_table = non_cont,U+00E4,U+00C4->U+00E4
用于不区分大小写的搜索。
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) charset_table = '0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451'POST /cli -d "
CREATE TABLE products(title text, price float) charset_table = '0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'charset_table' => '0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451'
]);utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451\'')await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451\'');utilsApi.sql("CREATE TABLE products(title text, price float) charset_table = '0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) charset_table = '0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451'", true);utils_api.sql("CREATE TABLE products(title text, price float) charset_table = '0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451'", Some(true)).await;table products {
charset_table = 0..9, A..Z->a..z, _, a..z, \
U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}除了字符和映射的定义外,还有几个内置别名可用。当前别名有:
chinesecjkcontenglishjapanesekoreannon_cont(non_cjk)russianthai
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) charset_table = '0..9, english, _'POST /cli -d "
CREATE TABLE products(title text, price float) charset_table = '0..9, english, _'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'charset_table' => '0..9, english, _'
]);utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'0..9, english, _\'')await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'0..9, english, _\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'0..9, english, _\'');utilsApi.sql("CREATE TABLE products(title text, price float) charset_table = '0..9, english, _'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) charset_table = '0..9, english, _'", true);utils_api.sql("CREATE TABLE products(title text, price float) charset_table = '0..9, english, _'", Some(true)).await;table products {
charset_table = 0..9, english, _
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}如果您想在搜索中支持不同的语言,定义所有语言的有效字符集和折叠规则可能是一项繁重的工作。我们为您简化了这一过程,提供了默认的字符集表 non_cont 和 cont,分别涵盖了非连续和连续(中文、日文、韩文、泰文)脚本的语言。在大多数情况下,这些字符集应足以满足您的需求。
请注意,以下语言当前不支持:
- 阿萨姆语
- 比什努普里亚语
- 布希德语
- 加罗语
- 苗族语
- 霍语
- 科米语
- 大花苗语
- 马巴语
- 迈蒂利语
- 马拉地语
- 门德语
- 姆鲁语
- 米耶内语
- 恩甘贝语
- 奥里亚语
- 桑塔利语
- 信德语
- 锡尔赫蒂语
所有其他列在Unicode语言列表中的语言默认均支持。 要同时处理 cont 和 non-cont 语言,请在配置文件中按如下所示设置选项(中文有一个例外):
CREATE TABLE products(title text, price float) charset_table = 'non_cont' ngram_len = '1' ngram_chars = 'cont'
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
POST /cli -d "CREATE TABLE products(title text, price float) charset_table = 'non_cont' ngram_len = '1' ngram_chars = 'cont'"
$index = new \Manticoresearch\Index($client);$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'charset_table' => 'non_cont',
'ngram_len' => '1',
'ngram_chars' => 'cont'
]);
##### Python:##### Python-asyncio:##### Javascript:##### java:##### C#:##### Rust:table products { charset_table = non_cont
ngram_len = 1
ngram_chars = cont
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
如果您不需要支持连续脚本语言,可以简单地排除%ngram_len [../../Creating_a_table/NLP_and_tokenization/Low-level_tokenization.md#ngram_len] %和%ngram_chars [../../Creating_a_table/NLP_and_tokenization/Low-level_tokenization.md#ngram_chars] %选项。有关这些选项的更多信息,请参阅相应的文档部分。要将一个字符映射到多个字符或反之,您可以使用regexp_filter。
blend_chars = +, &, U+23
blend_chars = +, &->+
混合字符列表。可选,默认为空。
混合字符既被索引为分隔符,也被索引为有效字符。例如,当 `&` 被定义为混合字符且索引文档中出现 `AT&T` 时,将索引三个不同的关键词:`at&t`、`at` 和 `t`。
此外,混合字符还可以影响索引,使得关键词的索引效果仿佛混合字符根本未被输入。这种行为在指定 blend_mode = trim_all 时尤为明显。例如,短语 some_thing 在 blend_mode = trim_all 下将被索引为 some、something 和 thing。
使用混合字符时应谨慎,因为将字符定义为混合字符意味着它不再是分隔符。
-
因此,如果您将逗号放入
blend_chars并搜索dog,cat,它将被视为单个标记dog,cat。如果dog,cat未 被索引为dog,cat,而仅作为dog cat,则不会匹配。 -
因此,这种行为应通过blend_mode设置进行控制。 通过将混合字符替换为空格获得的标记位置按常规分配,常规关键词将被索引,仿佛未指定任何
blend_chars。一个混合了混合字符和非混合字符的额外标记将放置在起始位置。例如,如果文本字段开头出现AT&T company,则at位置为1,t位置为2,company位置为3,同时AT&T也被赋予位置1,与开头的常规关键词混合。因此,查询AT&T或仅AT都会匹配该文档。短语查询"AT T"也会匹配,短语查询"AT&T company"亦然。 混合字符可能与查询语法中使用的特殊字符重叠,例如T-Mobile或@twitter。查询解析器会尽可能将混合字符作为混合字符处理。例如,如果hello @twitter在引号内(短语操作符),查询解析器会将@视为混合字符。但如果@不在引号内,则该字符会被视为操作符。因此,建议对关键词进行转义。
混合字符可以重新映射,使多个不同的混合字符规范化为一个基本形式。这在索引多个具有等效字形的替代 Unicode 代码点时非常有用。
CREATE TABLE products(title text, price float) blendchars = '+, &, U+23, @->'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) blend_chars = '+, &, U+23, @->_'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'blend_chars' => '+, &, U+23, @->_'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) blend_chars = \'+, &, U+23, @->_\'')await utilsApi.sql('CREATE TABLE products(title text, price float) blend_chars = \'+, &, U+23, @->_\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) blend_chars = \'+, &, U+23, @->_\'');utilsApi.sql("CREATE TABLE products(title text, price float) blend_chars = '+, &, U+23, @->_'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) blend_chars = '+, &, U+23, @->_'", true);utils_api.sql("CREATE TABLE products(title text, price float) blend_chars = '+, &, U+23, @->_'", Some(true)).await; blend_chars = +, &, U+23, @->_ type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### blend_mode
blend_mode = option [, option [, ...]]option = trim_none | trim_head | trim_tail | trim_both | trim_all | skip_pure
混合标记索引模式由 blend_mode 指令启用。
默认情况下,混合和非混合字符混合的标记会被完整索引。例如,当 `blend_chars` 中同时包含 at 符号和感叹号时,字符串 `@dude!` 会被索引为两个标记:`@dude!`(包含所有混合字符)和 `dude`(不含任何混合字符)。因此,查询 `@dude` **不会** 匹配它。
blend_mode 为此索引行为增加了灵活性。它接受一个逗号分隔的选项列表,每个选项指定一种标记索引变体。
如果指定了多个选项,将会索引同一标记的多个变体。常规关键字(通过用分隔符替换混合字符从该标记生成的)始终会被索引。
选项包括:
-
trim_none- 索引整个标记 -
trim_head- 修剪开头的混合字符,并索引结果标记 -
trim_tail- 修剪结尾的混合字符,并索引结果标记 -
trim_both- 修剪开头和结尾的混合字符,并索引结果标记 -
trim_all- 修剪开头、结尾和中间的混合字符,并索引结果标记 -
skip_pure- 如果标记纯粹由混合字符组成,则不索引该标记 使用上述示例字符串@dude!的blend_mode,设置blend_mode = trim_head, trim_tail会导致索引两个标记:@dude和dude!。使用trim_both不会有影响,因为修剪两端的混合字符后得到的dude已作为常规关键字被索引。使用trim_both索引@U.S.A.(假设点是混合字符)会索引U.S.A。最后,skip_pure允许忽略仅由混合字符组成的序列。例如,one @@@ two会被索引为one two,并作为短语匹配。默认情况下不是这样,因为完全混合的标记会被索引并影响第二个关键字的位置。 默认行为是索引整个标记,相当于blend_mode = trim_none。
请注意,即使使用默认模式 trim_none,如果假设 . 是混合字符,使用混合模式也会限制搜索:
-
.dog.在索引时会变成.dog. dog -
你将无法通过
dog.找到它。 使用更多模式会增加关键字匹配的可能性。 CREATE TABLE products(title text, price float) blend_mode = 'trim_tail, skip_pure' blend_chars = '+, &'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) blend_mode = 'trim_tail, skip_pure' blend_chars = '+, &'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'blend_mode' => 'trim_tail, skip_pure',
'blend_chars' => '+, &'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) blend_mode = \'trim_tail, skip_pure\' blend_chars = \'+, &\'')await utilsApi.sql('CREATE TABLE products(title text, price float) blend_mode = \'trim_tail, skip_pure\' blend_chars = \'+, &\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) blend_mode = \'trim_tail, skip_pure\' blend_chars = \'+, &\'');utilsApi.sql("CREATE TABLE products(title text, price float) blend_mode = 'trim_tail, skip_pure' blend_chars = '+, &'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) blend_mode = 'trim_tail, skip_pure' blend_chars = '+, &'", true);utils_api.sql("CREATE TABLE products(title text, price float) blend_mode = 'trim_tail, skip_pure' blend_chars = '+, &'", Some(true)).await; blend_mode = trim_tail, skip_pure blend_chars = +, &
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### min_word_len
min_word_len = lengthmin_word_len 是 Manticore 中的一个可选索引配置选项,指定最小索引词长。默认值为 1,表示所有内容都会被索引。
只有长度不小于该最小值的词才会被索引。例如,如果 min_word_len 是 4,则 'the' 不会被索引,但 'they' 会被索引。
CREATE TABLE products(title text, price float) min_word_len = '4'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) min_word_len = '4'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'min_word_len' => '4'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) min_word_len = \'4\'')await utilsApi.sql('CREATE TABLE products(title text, price float) min_word_len = \'4\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) min_word_len = \'4\'');utilsApi.sql("CREATE TABLE products(title text, price float) min_word_len = '4'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) min_word_len = '4'", true);utils_api.sql("CREATE TABLE products(title text, price float) min_word_len = '4'", Some(true)).await; min_word_len = 4 type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### ngram_len
ngram_len = 1N-gram 长度,用于 N-gram 索引。可选,默认值为 0(禁用 N-gram 索引)。已知值为 0 和 1。
N-gram 为连续书写语言的无分词文本提供基本支持。使用连续书写语言搜索的问题在于缺少明确的词间分隔符。在某些情况下,你可能不想使用基于词典的分词,比如%中文的分词 [../../Creating_a_table/NLP_and_tokenization/Languages_with_continuous_scripts.md] %。在这些情况下,N-gram 分词也可能效果良好。
启用此功能时,这些语言的文本流(或任何在 ngram_chars 中定义的字符)将作为 N-gram 索引。例如,如果输入文本是 "ABCDEF"(其中 A 到 F 代表某种语言字符),且 ngram_len 是 1,则会被索引为 "A B C D E F"。目前仅支持 ngram_len=1。只有列在 ngram_chars 表中的字符会被这样拆分;其他字符不受影响。
请注意,如果搜索查询已分词,即单词间有分隔符,则在应用端将单词用引号包裹并使用扩展模式,仍能正确匹配未分词的文本。例如,假设原始查询是 BC DEF。在应用端包裹引号后,应为 "BC" "DEF"(带引号)。该查询传递给 Manticore 后,内部也会拆分成 1-gram,变成 "B C" "D E F" 查询,仍带有作为短语匹配操作符的引号。即使文本中没有分隔符,也能匹配该文本。
即使搜索查询未分词,Manticore 仍应产生良好结果,得益于基于短语的排名:它会将更接近的短语匹配(对于 N-gram 词来说,意味着更接近的多字符词匹配)排在前面。
CREATE TABLE products(title text, price float) ngram_chars = 'cont' ngram_len = '1'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) ngram_chars = 'cont' ngram_len = '1'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'ngram_chars' => 'cont',
'ngram_len' => '1'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) ngram_chars = \'cont\' ngram_len = \'1\'')await utilsApi.sql('CREATE TABLE products(title text, price float) ngram_chars = \'cont\' ngram_len = \'1\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) ngram_chars = \'cont\' ngram_len = \'1\'');utilsApi.sql("CREATE TABLE products(title text, price float) ngram_chars = 'cont' ngram_len = '1'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) ngram_chars = 'cont' ngram_len = '1'", true);utils_api.sql("CREATE TABLE products(title text, price float) ngram_chars = 'cont' ngram_len = '1'", Some(true)).await; ngram_chars = cont ngram_len = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### ngram_chars
ngram_chars = contngram_chars = cont, U+3000..U+2FA1F
N-gram 字符列表。可选,默认为空。
与 %ngram_len [../../Creating_a_table/NLP_and_tokenization/Low-level_tokenization.md#ngram_len] % 配合使用时,此列表定义了哪些字符序列会被用于 N-gram 提取。由其他字符组成的单词不会受到 N-gram 索引功能的影响。值的格式与 %charset_table [../../Creating_a_table/NLP_and_tokenization/Low-level_tokenization.md#charset_table] % 相同。N-gram 字符不能出现在 %charset_table [../../Creating_a_table/NLP_and_tokenization/Low-level_tokenization.md#charset_table] % 中。
CREATE TABLE products(title text, price float) ngram_chars = 'U+3000..U+2FA1F' ngram_len = '1'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) ngram_chars = 'U+3000..U+2FA1F' ngram_len = '1'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'ngram_chars' => 'U+3000..U+2FA1F',
'ngram_len' => '1'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) ngram_chars = \'U+3000..U+2FA1F\' ngram_len = \'1\'')await utilsApi.sql('CREATE TABLE products(title text, price float) ngram_chars = \'U+3000..U+2FA1F\' ngram_len = \'1\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) ngram_chars = \'U+3000..U+2FA1F\' ngram_len = \'1\'');utilsApi.sql("CREATE TABLE products(title text, price float) ngram_chars = 'U+3000..U+2FA1F' ngram_len = '1'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) ngram_chars = 'U+3000..U+2FA1F' ngram_len = '1'", true);utils_api.sql("CREATE TABLE products(title text, price float) ngram_chars = 'U+3000..U+2FA1F' ngram_len = '1'", Some(true)).await; ngram_chars = U+3000..U+2FA1F ngram_len = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
你也可以像示例中那样使用我们默认的 N-gram 表的别名。在大多数情况下,这应该足够了。
CREATE TABLE products(title text, price float) ngram_chars = 'cont' ngram_len = '1'POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) ngram_chars = 'cont' ngram_len = '1'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'ngram_chars' => 'cont',
'ngram_len' => '1'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) ngram_chars = \'cont\' ngram_len = \'1\'')await utilsApi.sql('CREATE TABLE products(title text, price float) ngram_chars = \'cont\' ngram_len = \'1\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) ngram_chars = \'cont\' ngram_len = \'1\'');utilsApi.sql("CREATE TABLE products(title text, price float) ngram_chars = 'cont' ngram_len = '1'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) ngram_chars = 'cont' ngram_len = '1'", true);utils_api.sql("CREATE TABLE products(title text, price float) ngram_chars = 'cont' ngram_len = '1'", Some(true)).await; ngram_chars = cont ngram_len = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### ignore_chars
ignore_chars = U+AD忽略字符列表。可选,默认为空。
当某些字符(如软连字符 U+00AD)不仅应被视为分隔符,而应完全忽略时,此功能非常有用。例如,如果 '-' 不在 charset_table 中,文本 "abc-def" 将被索引为 "abc" 和 "def" 两个关键词。相反,如果 '-' 被添加到 ignore_chars 列表中,同样的文本将被索引为单个关键词 "abcdef"。
语法与 charset_table 相同,但只允许声明字符,不允许映射它们。此外,被忽略的字符不能出现在 charset_table 中。
CREATE TABLE products(title text, price float) ignore_chars = 'U+AD'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) ignore_chars = 'U+AD'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'ignore_chars' => 'U+AD'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) ignore_chars = \'U+AD\'')await utilsApi.sql('CREATE TABLE products(title text, price float) ignore_chars = \'U+AD\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) ignore_chars = \'U+AD\'');utilsApi.sql("CREATE TABLE products(title text, price float) ignore_chars = 'U+AD'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) ignore_chars = 'U+AD'", true);utils_api.sql("CREATE TABLE products(title text, price float) ignore_chars = 'U+AD'", Some(true)).await; ignore_chars = U+AD type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### bigram_index
bigram_index = {none|all|first_freq|both_freq}二元组索引模式。可选,默认无。
二元组索引是一种加速短语搜索的功能。索引时,它会将所有或部分相邻词对的文档列表存储到索引中。该列表随后可在搜索时用来显著加快短语或子短语匹配。
bigram_index 控制特定词对的选择。已知的模式有:
-
all,索引每一个词对 -
first_freq,仅索引第一个词是频繁词列表中的词的词对(见 bigram_freq_words)。例如,设置bigram_freq_words = the, in, i, a时,索引文本 "alone in the dark" 会存储 "in the" 和 "the dark" 这两个二元组,因为它们以频繁词("in" 或 "the")开头,但 "alone in" 不会被索引,因为 "in" 是该词对的第二个词。 -
both_freq,仅索引两个词都是频繁词的词对。以同样的例子,使用此模式索引 "alone in the dark" 只会存储 "in the"(从搜索角度看是最差的情况),其他词对不会被存储。 对于大多数用例,both_freq是最佳模式,但具体情况可能有所不同。 需要注意的是,bigram_index仅在分词层面工作,不考虑诸如morphology、wordforms或stopwords等转换。这意味着它创建的词元非常直接,使短语搜索更精确和严格。虽然这可以提高短语匹配的准确性,但也降低了系统识别词形变化或词语变体的能力。
CREATE TABLE products(title text, price float) bigram_freq_words = 'the, a, you, i' bigram_index = 'both_freq'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) bigram_freq_words = 'the, a, you, i' bigram_index = 'both_freq'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'bigram_freq_words' => 'the, a, you, i',
'bigram_index' => 'both_freq'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) bigram_freq_words = \'the, a, you, i\' bigram_index = \'both_freq\'')await utilsApi.sql('CREATE TABLE products(title text, price float) bigram_freq_words = \'the, a, you, i\' bigram_index = \'both_freq\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) bigram_freq_words = \'the, a, you, i\' bigram_index = \'both_freq\'');utilsApi.sql("CREATE TABLE products(title text, price float) bigram_freq_words = 'the, a, you, i' bigram_index = 'both_freq'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) bigram_freq_words = 'the, a, you, i' bigram_index = 'both_freq'", true);utils_api.sql("CREATE TABLE products(title text, price float) bigram_freq_words = 'the, a, you, i' bigram_index = 'both_freq'", Some(true)).await; bigram_index = both_freq bigram_freq_words = the, a, you, i
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### bigram_freq_words
bigram_freq_words = the, a, you, i在索引二元组时被视为“频繁”的关键词列表。可选,默认为空。
一些二元索引模式(参见 %bigram_index [../../Creating_a_table/NLP_and_tokenization/Low-level_tokenization.md#bigram_index] %)需要定义一个频繁关键词列表。这些**不**应与停用词混淆。停用词在索引和搜索时会被完全剔除。频繁关键词仅被二元组用来判断是否索引当前的词对。
bigram_freq_words 允许你定义这样一个关键词列表。
CREATE TABLE products(title text, price float) bigram_freq_words = 'the, a, you, i' bigram_index = 'first_freq'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) bigram_freq_words = 'the, a, you, i' bigram_index = 'first_freq'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'bigram_freq_words' => 'the, a, you, i',
'bigram_index' => 'first_freq'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) bigram_freq_words = \'the, a, you, i\' bigram_index = \'first_freq\'')await utilsApi.sql('CREATE TABLE products(title text, price float) bigram_freq_words = \'the, a, you, i\' bigram_index = \'first_freq\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) bigram_freq_words = \'the, a, you, i\' bigram_index = \'first_freq\'');utilsApi.sql("CREATE TABLE products(title text, price float) bigram_freq_words = 'the, a, you, i' bigram_index = 'first_freq'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) bigram_freq_words = 'the, a, you, i' bigram_index = 'first_freq'", true);utils_api.sql("CREATE TABLE products(title text, price float) bigram_freq_words = 'the, a, you, i' bigram_index = 'first_freq'", Some(true)).await; bigram_freq_words = the, a, you, i bigram_index = first_freq
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### dict
dict = {keywords|crc}所使用的关键词字典类型由两个已知值之一标识,'crc' 或 'keywords'。这是可选的,默认值为 'keywords'。
使用关键词字典模式(dict=keywords)可以显著减少索引负担,并在大规模集合上启用子串搜索。此模式可用于普通表和 RT 表。
CRC 字典不会在索引中存储原始关键词文本。相反,它们在搜索和索引过程中用一个控制和校验值(使用 FNV64 计算)替代关键词。该值在索引内部使用。这种方法有两个缺点:
-
首先,不同关键词对之间存在控制和校验值冲突的风险。该风险随着索引中唯一关键词数量的增加而增加。尽管如此,这个问题较小,因为在一个包含 10 亿条目的字典中,单个 FNV64 冲突的概率大约是 1/16,即 6.25%。大多数字典的关键词数量远少于 10 亿,因为典型的口语人类语言词形数量在 1 到 1000 万之间。
-
其次,更重要的是,使用控制和校验值进行子串搜索并不简单。Manticore 通过预先索引所有可能的子串作为独立关键词来解决此问题(参见 min_prefix_len,min_infix_len 指令)。这种方法还有一个额外优点,即以最快的方式匹配子串。然而,预索引所有子串会显著增加索引大小(通常增加 3-10 倍或更多),并随后影响索引时间,使得在大型索引上进行子串搜索变得不太实用。 关键词字典解决了这两个问题。它在索引中存储关键词,并在搜索时执行通配符扩展。例如,搜索
test*前缀时,内部可能扩展为基于字典内容的 'test|tests|testing' 查询。此扩展过程对应用程序完全透明,唯一的区别是所有匹配关键词的单独统计数据也会被报告。 对于子串(中缀)搜索,可以使用扩展通配符。特殊字符如?和%与子串(中缀)搜索兼容(例如,t?st*,run%,*abc*)。请注意,通配符操作符 和 REGEX 仅在dict=keywords时有效。
使用关键词字典索引的速度大约比常规非子串索引慢 1.1 到 1.3 倍,但明显快于子串索引(无论是前缀还是中缀)。索引大小应仅比标准非子串表略大,总差异在 1% 到 10% 之间。常规关键词搜索的时间在这三种索引类型(CRC 非子串、CRC 子串、关键词)中应几乎相同或相等。子串搜索时间会根据匹配给定子串的实际关键词数量(即搜索词扩展成多少关键词)显著波动。匹配关键词的最大数量受 expansion_limit 指令限制。
总之,关键词和 CRC 字典为子串搜索提供了两种不同的权衡选择。你可以选择牺牲索引时间和索引大小以获得最快的最坏情况搜索(CRC 字典),或者最小化索引时间影响,但在前缀扩展成大量关键词时牺牲最坏情况搜索时间(关键词字典)。
CREATE TABLE products(title text, price float) dict = 'keywords'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) dict = 'keywords'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'dict' => 'keywords'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) dict = \'keywords\'')await utilsApi.sql('CREATE TABLE products(title text, price float) dict = \'keywords\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) dict = \'keywords\'');utilsApi.sql("CREATE TABLE products(title text, price float) dict = 'keywords'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) dict = 'keywords'", true);utils_api.sql("CREATE TABLE products(title text, price float) dict = 'keywords'", Some(true)).await; dict = keywords type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### embedded_limit
embedded_limit = size嵌入式例外、词形或停用词文件大小限制。可选,默认值为 16K。
当你创建表时,上述文件可以与表一起外部保存,或者直接嵌入到表中。大小低于 `embedded_limit` 的文件会存储到表中。对于较大的文件,仅存储文件名。这也简化了将表文件移动到另一台机器的过程;你可能只需复制一个文件即可。
对于较小的文件,这种嵌入减少了表所依赖的外部文件数量,有助于维护。但同时,将一个100 MB的词形字典嵌入到一个微小的增量表中是没有意义的。因此需要有一个大小阈值,而embedded_limit就是这个阈值。
table products {
embedded_limit = 32K
- CONFIG
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### global_idf
global_idf = /path/to/global.idf全局(集群范围)关键词IDF文件的路径。可选,默认为空(使用本地IDF)。
在多表集群中,每个关键词的频率很可能在不同的表之间有所不同。这意味着当排名函数使用基于TF-IDF的值(如BM25系列因子)时,结果可能会根据它们所在的集群节点而略有不同。
解决该问题的最简单方法是创建并使用全局频率字典,简称全局IDF文件。该指令允许您指定该文件的位置。建议(但不强制)使用.idf扩展名。当为给定表指定了IDF文件且 OPTION global_idf 设置为1时,引擎将使用global_idf文件中的关键词频率和集合文档计数,而不仅仅是本地表。这样,IDF及其依赖的值将在整个集群中保持一致。
IDF文件可以被多个表共享。即使许多表引用该文件,searchd也只会加载IDF文件的单个副本。如果IDF文件的内容发生变化,可以通过SIGHUP加载新内容。
您可以使用indextool工具构建.idf文件,先使用--dumpdict dict.txt --stats开关导出字典,然后使用--buildidf将其转换为.idf格式,最后使用--mergeidf合并整个集群的所有.idf文件。
CREATE TABLE products(title text, price float) global_idf = '/usr/local/manticore/var/global.idf'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) global_idf = '/usr/local/manticore/var/global.idf'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'global_idf' => '/usr/local/manticore/var/global.idf'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) global_idf = \'/usr/local/manticore/var/global.idf\'')await utilsApi.sql('CREATE TABLE products(title text, price float) global_idf = \'/usr/local/manticore/var/global.idf\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) global_idf = \'/usr/local/manticore/var/global.idf\'');utilsApi.sql("CREATE TABLE products(title text, price float) global_idf = '/usr/local/manticore/var/global.idf'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) global_idf = '/usr/local/manticore/var/global.idf'", true);utils_api.sql("CREATE TABLE products(title text, price float) global_idf = '/usr/local/manticore/var/global.idf'", Some(true)).await; global_idf = /usr/local/manticore/var/global.idf type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### hitless_words
hitless_words = {all|path/to/file}无命中词列表。可选,允许的值为'all',或一个列表文件名。
默认情况下,Manticore全文索引不仅存储每个关键词匹配的文档列表,还存储其在文档中的位置列表(称为hitlist)。Hitlist支持短语、邻近、严格顺序及其他高级搜索类型,以及短语邻近排名。然而,对于某些频繁关键词(尽管频繁但无法被停止词过滤),hitlist可能非常庞大,导致查询时处理缓慢。此外,在某些情况下,我们可能只关心布尔关键词匹配,根本不需要基于位置的搜索操作符(如短语匹配)或短语排名。
hitless_words允许您创建完全没有位置信息(hitlist)的索引,或对特定关键词跳过位置信息。
无命中索引通常比相应的常规全文索引占用更少空间(大约可节省1.5倍)。索引和搜索速度都应更快,但代价是缺少位置查询和排名支持。
如果在位置查询(例如短语查询)中使用,无命中词会被从查询中剔除,并作为无位置的操作数使用。例如,如果“hello”和“world”是无命中词,而“simon”和“says”不是无命中词,则短语查询 "simon says hello world" 会被转换为 ("simon says" & hello & world),匹配文档中任意位置的“hello”和“world”,以及作为精确短语的“simon says”。
仅包含无命中词的位置信息查询将导致空短语节点,因此整个查询将返回空结果并发出警告。如果整个字典都是无命中词(使用all),则只能在相应索引上使用布尔匹配。
CREATE TABLE products(title text, price float) hitless_words = 'all'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) hitless_words = 'all'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'hitless_words' => 'all'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) hitless_words = \'all\'')await utilsApi.sql('CREATE TABLE products(title text, price float) hitless_words = \'all\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) hitless_words = \'all\'');utilsApi.sql("CREATE TABLE products(title text, price float) hitless_words = 'all'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) hitless_words = 'all'", true);utils_api.sql("CREATE TABLE products(title text, price float) hitless_words = 'all'", Some(true)).await; hitless_words = all type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### index_field_lengths
index_field_lengths = {0|1}启用计算和存储字段长度(包括每文档和每索引的平均值)到全文索引中。可选,默认值为0(不计算和存储)。
当`index_field_lengths`设置为1时,Manticore将:
-
为每个全文字段创建相应的长度属性,名称相同但带有
__len后缀 -
计算每个文档的字段长度(以关键词计数)并存储到相应属性中
-
计算每个索引的平均值。长度属性将具有特殊的TOKENCOUNT类型,但其值实际上是常规的32位整数,且其值通常是可访问的。 BM25A() 和 BM25F() 表达式排序器中的函数基于这些长度,并且需要启用
index_field_lengths。历史上,Manticore 使用了一个简化的、精简版的 BM25,该版本与完整函数不同,不考虑文档长度。现在也支持 BM25 的完整变体及其多字段扩展,称为 BM25F。它们分别需要每个文档长度和每个字段长度。因此需要额外的指令。 CREATE TABLE products(title text, price float) index_field_lengths = '1'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) index_field_lengths = '1'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'index_field_lengths' => '1'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) index_field_lengths = \'1\'')await utilsApi.sql('CREATE TABLE products(title text, price float) index_field_lengths = \'1\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) index_field_lengths = \'1\'');utilsApi.sql("CREATE TABLE products(title text, price float) index_field_lengths = '1'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) index_field_lengths = '1'", true);utils_api.sql("CREATE TABLE products(title text, price float) index_field_lengths = '1'", Some(true)).await; index_field_lengths = 1 type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### index_token_filter
index_token_filter = my_lib.so:custom_blend:chars=@#&全文索引时的索引时令牌过滤器。可选,默认为空。
index_token_filter 指令指定全文索引时的可选索引时令牌过滤器。该指令用于创建一个根据自定义规则生成令牌的自定义分词器。该过滤器由索引器在将源数据索引到普通表时创建,或由 RT 表在处理 `INSERT` 或 `REPLACE` 语句时创建。插件使用格式 `library name:plugin name:optional string of settings` 定义。例如,`my_lib.so:custom_blend:chars=@#&`。
CREATE TABLE products(title text, price float) index_token_filter = 'my_lib.so:custom_blend:chars=@#&' POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) index_token_filter = 'my_lib.so:custom_blend:chars=@#&'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'index_token_filter' => 'my_lib.so:custom_blend:chars=@#&'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) index_token_filter = \'my_lib.so:custom_blend:chars=@#&\'')await utilsApi.sql('CREATE TABLE products(title text, price float) index_token_filter = \'my_lib.so:custom_blend:chars=@#&\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) index_token_filter = \'my_lib.so:custom_blend:chars=@#&\'');utilsApi.sql("CREATE TABLE products(title text, price float) index_token_filter = 'my_lib.so:custom_blend:chars=@#&'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) index_token_filter = 'my_lib.so:custom_blend:chars=@#&'", true);utils_api.sql("CREATE TABLE products(title text, price float) index_token_filter = 'my_lib.so:custom_blend:chars=@#&'", Some(true)).await; index_token_filter = my_lib.so:custom_blend:chars=@#& type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### overshort_step
overshort_step = {0|1}对过短(少于 min_word_len)关键词的位置增量。可选,允许值为 0 和 1,默认是 1。
CREATE TABLE products(title text, price float) overshort_step = '1'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) overshort_step = '1'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'overshort_step' => '1'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) overshort_step = \'1\'')utilsApi.sql('CREATE TABLE products(title text, price float) overshort_step = \'1\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) overshort_step = \'1\'');utilsApi.sql("CREATE TABLE products(title text, price float) overshort_step = '1'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) overshort_step = '1'", true);utils_api.sql("CREATE TABLE products(title text, price float) overshort_step = '1'", Some(true)).await; overshort_step = 1 type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### phrase_boundary
phrase_boundary = ., ?, !, U+2026 # horizontal ellipsis短语边界字符列表。可选,默认为空。
该列表控制哪些字符将被视为短语边界,以调整词的位置并通过邻近搜索实现短语级搜索模拟。语法类似于 %charset_table [../../Creating_a_table/NLP_and_tokenization/Low-level_tokenization.md#charset_table] %,但不允许映射,且边界字符不得与其他任何内容重叠。
在短语边界处,将向当前词位置添加额外的词位置增量(由 phrase_boundary_step 指定)。这使得通过邻近查询实现短语级搜索成为可能:不同短语中的词将保证相距超过 phrase_boundary_step;因此在该距离内的邻近搜索等同于短语级搜索。 只有当该字符后面跟着分隔符时,才会触发短语边界条件;这是为了避免将缩写如 S.T.A.L.K.E.R 或 URL 视为多个短语。 CREATE TABLE products(title text, price float) phrase_boundary = '., ?, !, U+2026' phrase_boundary_step = '10' POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) phrase_boundary = '., ?, !, U+2026' phrase_boundary_step = '10'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'phrase_boundary' => '., ?, !, U+2026',
'phrase_boundary_step' => '10'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) phrase_boundary = \'., ?, !, U+2026\' phrase_boundary_step = \'10\'')
await utilsApi.sql('CREATE TABLE products(title text, price float) phrase_boundary = \'., ?, !, U+2026\' phrase_boundary_step = \'10\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) phrase_boundary = \'., ?, !, U+2026\' phrase_boundary_step = \'10\'');utilsApi.sql("CREATE TABLE products(title text, price float) phrase_boundary = '., ?, !, U+2026' phrase_boundary_step = '10'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) phrase_boundary = '., ?, !, U+2026' phrase_boundary_step = '10'", true);utils_api.sql("CREATE TABLE products(title text, price float) phrase_boundary = '., ?, !, U+2026' phrase_boundary_step = '10'", Some(true)).await; phrase_boundary = ., ?, !, U+2026 phrase_boundary_step = 10
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### phrase_boundary_step
phrase_boundary_step = 100短语边界词位置增量。可选,默认是 0。
在短语边界处,当前词位置将额外增加此数值。
CREATE TABLE products(title text, price float) phrase_boundary_step = '100' phrase_boundary = '., ?, !, U+2026' POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) phrase_boundary_step = '100' phrase_boundary = '., ?, !, U+2026'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'phrase_boundary_step' => '100',
'phrase_boundary' => '., ?, !, U+2026'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) phrase_boundary_step = \'100\' phrase_boundary = \'., ?, !, U+2026\'')
await utilsApi.sql('CREATE TABLE products(title text, price float) phrase_boundary_step = \'100\' phrase_boundary = \'., ?, !, U+2026\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) phrase_boundary_step = \'100\' phrase_boundary = \'., ?, !, U+2026\'');utilsApi.sql("CREATE TABLE products(title text, price float) phrase_boundary_step = '100' phrase_boundary = '., ?, !, U+2026'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) phrase_boundary_step = '100' phrase_boundary = '., ?, !, U+2026'", true);utils_api.sql("CREATE TABLE products(title text, price float) phrase_boundary_step = '100' phrase_boundary = '., ?, !, U+2026'", Some(true)).await; phrase_boundary_step = 100 phrase_boundary = ., ?, !, U+2026
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
### regexp_filter
# index '13"' as '13inch'regexp_filter = \b(\d+)\" => \1inch
# index 'blue' or 'red' as 'color'
regexp_filter = (blue|red) => color
正则表达式(regexps)用于过滤字段和查询。此指令是可选的,可多值,默认值为空的正则表达式列表。Manticore Search 使用的正则表达式引擎是 Google 的 RE2,以其速度和安全性著称。有关 RE2 支持的语法的详细信息,您可以访问 %RE2 语法指南 [https://github.com/google/re2/wiki/Syntax] %。
在某些应用中,例如产品搜索,可能有多种方式来指代一个产品、型号或属性。例如,`iPhone 3gs` 和 `iPhone 3 gs`(甚至 `iPhone3 gs`)很可能指的是同一款产品。另一个例子是表达笔记本屏幕尺寸的不同方式,如 `13-inch`、`13 inch`、`13"` 或 `13in`。
正则表达式提供了一种机制,用于指定处理此类情况的规则。在第一个例子中,您可能会使用一个词形文件来处理少量的 iPhone 型号,但在第二个例子中,更好的是指定规则,将“13-inch”和“13in”规范化为相同的形式。
列在 regexp_filter 中的正则表达式按列出顺序应用,在尽可能早的阶段应用,早于任何其他处理(包括例外),甚至早于分词。也就是说,正则表达式应用于索引时的原始源字段,以及搜索时的原始搜索查询文本。
CREATE TABLE products(title text, price float) regexp_filter = '(blue|red) => color'
POST /cli -d "
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) regexp_filter = '(blue|red) => color'"$index = new \Manticoresearch\Index($client);
$index->setName('products');$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'regexp_filter' => '(blue|red) => color'
]);
##### Python:
utilsApi.sql('CREATE TABLE products(title text, price float) regexp_filter = \'(blue|red) => color\'')await utilsApi.sql('CREATE TABLE products(title text, price float) regexp_filter = \'(blue|red) => color\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) regexp_filter = \'(blue|red) => color\'');utilsApi.sql("CREATE TABLE products(title text, price float) regexp_filter = '(blue|red) => color'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) regexp_filter = '(blue|red) => color'", true);utils_api.sql("CREATE TABLE products(title text, price float) regexp_filter = '(blue|red) => color'", Some(true)).await; # index '13"' as '13inch' regexp_filter = \b(\d+)\" => \1inch
# index 'blue' or 'red' as 'color'
regexp_filter = (blue|red) => color
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}
rt_attr_uint = price
}通配符搜索是一种常见的文本搜索类型。在 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*