Поиск с подстановочными знаками (wildcard) — это распространенный тип текстового поиска. В Manticore он выполняется на уровне словаря. По умолчанию как обычные таблицы, так и RT-таблицы используют тип словаря под названием dict. В этом режиме слова хранятся как есть, поэтому включение поиска с подстановочными знаками не влияет на размер таблицы. При выполнении такого поиска словарь просматривается, чтобы найти все возможные варианты раскрытия слова с подстановочным знаком. Это раскрытие может быть проблематичным с точки зрения вычислительных затрат в момент выполнения запроса, когда раскрываемое слово дает много вариантов или варианты имеют огромные списки совпадений (hitlists), особенно в случае инфиксов, когда подстановочный знак добавляется в начало и конец слова. Чтобы избежать таких проблем, можно использовать expansion_limit.
min_prefix_len = length
Эта настройка определяет минимальную длину префикса слова для индексации и поиска. По умолчанию установлено значение 0, что означает, что префиксы не разрешены.
Префиксы позволяют выполнять поиск с подстановочными знаками с помощью шаблонов вида началослова*.
Например, если слово "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 или при отключении любой из вышеуказанных опций невозможно различить префиксы и полные слова, и точные совпадения слов не могут быть ранжированы выше.
Когда минимальная длина инфикса установлена в положительное число, минимальная длина префикса всегда считается равной 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.
При включении инфиксы позволяют выполнять поиск с подстановочными знаками с шаблонами терминов, такими как начало*, *конец, *середина* и так далее. Это также позволяет отключать слишком короткие подстановочные знаки, если поиск по ним слишком затратен.
Если выполняются следующие условия, 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 МБ базовый (без подстрок)
- 24.3 МБ (в 3.8 раза больше) с min_prefix_len = 3
- 22.2 МБ (в 3.5 раза больше) с min_prefix_len = 3, max_substring_len = 8
- 19.3 МБ (в 3.0 раза больше) с min_prefix_len = 3, max_substring_len = 6
- 94.3 МБ (в 14.7 раза больше) с min_infix_len = 3
- 84.6 МБ (в 13.2 раза больше) с min_infix_len = 3, max_substring_len = 8
- 70.7 МБ (в 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 влияет на веса результатов поиска и как "runsy" находится по "runs" без необходимости добавлять звездочку:
- 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, поэтому вы можете использовать те же разделители, что и в индексируемых данных.
Когда активна индексация ngram_len, стоп-слова, состоящие из символов, подпадающих под ngram_chars, сами токенизируются в N-граммы. Таким образом, каждая отдельная N-грамма становится отдельным стоп-словом. Например, при ngram_len=1 и подходящих ngram_chars стоп-слово test будет интерпретировано как t, e, s, t — четыре различных стоп-слова.
Файлы стоп-слов можно создавать вручную или полуавтоматически. Индексатор предоставляет режим, который создает частотный словарь таблицы, отсортированный по частоте ключевых слов. Верхние ключевые слова из этого словаря обычно можно использовать как стоп-слова. Подробнее см. переключатели --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
}stopwords_list = 'value1; value2; ...'
Параметр stopwords_list позволяет указать стоп-слова непосредственно в операторе CREATE TABLE. Он поддерживается только в режиме RT.
Значения должны быть разделены точкой с запятой (;). Если необходимо использовать точку с запятой как обычный символ, её нужно экранировать обратной косой чертой (\;).
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
CREATE TABLE products(title text, price float) stopwords_list = 'a; the'POST /cli -d "
CREATE TABLE products(title text, price float) stopwords_list = 'a; the'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'stopwords_list' => 'a; the'
]);utilsApi.sql('CREATE TABLE products(title text, price float) stopwords_list = \'a; the\'')await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords_list = \'a; the\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords_list = \'a; the\'');utilsApi.sql("CREATE TABLE products(title text, price float) stopwords_list = 'a; the'", true);utilsApi.sql("CREATE TABLE products(title text, price float) stopwords_list = 'a; the'", true);utils_api.sql("CREATE TABLE products(title text, price float) stopwords_list = 'a; the'", Some(true)).await;stopword_step={0|1}
Параметр 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}
Определяет, применять ли стоп-слова до или после стемминга. Необязательный параметр, по умолчанию 0 (применять фильтр стоп-слов после стемминга).
По умолчанию стоп-слова сами подвергаются стеммингу, а затем применяются к токенам после стемминга (или любой другой морфологической обработки). Это означает, что токен пропускается, когда stem(токен) равен stem(стоп-слово). Такое поведение по умолчанию может привести к неожиданным результатам, когда токен ошибочно сводится к стоп-корню. Например, "Andes" может быть приведено к "and", поэтому, когда "and" является стоп-словом, "Andes" также пропускается.
Однако вы можете изменить это поведение, включив директиву stopwords_unstemmed. При её включении стоп-слова применяются до стемминга (и, следовательно, к исходным формам слов), и токены пропускаются, когда токен равен стоп-слову.
- 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 таблице, необходимо выполнить ротацию таблицы, чтобы подхватить изменения в файле форм слов.
- 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 разработана для эффективной работы с большими словарями. Они умеренно влияют на скорость индексации; например, словарь с 1 миллионом записей замедляет полнотекстовую индексацию примерно в 1,5 раза. Скорость поиска не затрагивается вообще. Дополнительное влияние на оперативную память примерно равно размеру файла словаря, и словари являются общими для всех таблиц. Например, если один и тот же файл форм слов размером 50 МБ указан для 10 разных таблиц, дополнительное использование оперативной памяти searchd составит около 50 МБ.
Файл словаря должен быть в простом текстовом формате. Каждая строка должна содержать исходную и целевую формы слов в кодировке UTF-8, разделённые знаком 'больше'. Правила из charset_table будут применены при загрузке файла. Следовательно, если вы не изменяете charset_table, ваши формы слов будут нечувствительны к регистру, как и другие полнотекстовые индексируемые данные. Ниже приведён пример содержимого файла:
- Example
walks > walk
walked > walk
walking > walkВ комплекте есть утилита под названием Spelldump, которая помогает создать файл словаря в формате, читаемом Manticore. Утилита может читать исходные файлы словарей .dict и .aff в формате ispell или MySpell, поставляемые в комплекте с 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_list = 'source-form > destination-form; ...'
Настройка wordforms_list позволяет указать формы слов непосредственно в операторе CREATE TABLE. Поддерживается только в режиме RT.
Значения должны быть разделены точкой с запятой (;). Поскольку формы слов могут содержать > или => в качестве разделителей и, возможно, другие специальные символы, убедитесь, что экранируете точки с запятой, если они являются частью самой формы (например, \;).
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
CREATE TABLE products(title text, price float) wordforms_list = 'walks > walk; walked > walk'POST /cli -d "
CREATE TABLE products(title text, price float) wordforms_list = 'walks > walk; walked > walk'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'wordforms_list' => 'walks > walk; walked > walk'
]);utilsApi.sql('CREATE TABLE products(title text, price float) wordforms_list = \'walks > walk; walked > walk\'')await utilsApi.sql('CREATE TABLE products(title text, price float) wordforms_list = \'walks > walk; walked > walk\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) wordforms_list = \'walks > walk; walked > walk\'');utilsApi.sql("CREATE TABLE products(title text, price float) wordforms_list = 'walks > walk; walked > walk'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) wordforms_list = 'walks > walk; walked > walk'", true);utils_api.sql("CREATE TABLE products(title text, price float) wordforms_list = 'walks > walk; walked > walk'", Some(true)).await;Исключения (также известные как синонимы) позволяют сопоставить один или несколько токенов (включая токены с символами, которые обычно исключаются) с одним ключевым словом. Они похожи на словоформы тем, что также выполняют сопоставление, но имеют ряд важных отличий.
Краткое описание отличий от словоформ следующее:
| Исключения | Словоформы |
|---|---|
| Чувствительны к регистру | Нечувствительны к регистру |
| Могут использовать специальные символы, которых нет в charset_table | Полностью подчиняются charset_table |
| Плохо справляются с огромными словарями | Предназначены для обработки миллионов записей |
exceptions = path/to/exceptions.txt
Файл исключений для токенизации. Необязательный, по умолчанию пустой. В режиме RT допускаются только абсолютные пути.
Ожидаемый формат файла — обычный текст, по одному исключению на строку. Формат строки следующий:
source-form => destination-form
Пример файла:
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++. Приведённый выше пример сделает именно это, полностью независимо от того, какие символы есть в таблице, а каких нет.
При использовании обычной таблицы необходимо выполнить ротацию таблицы, чтобы включить изменения из файла исключений. В случае таблицы реального времени изменения будут применяться только к новым документам.
- 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
}exceptions_list = 'source-form => destination-form; ...'
Настройка exceptions_list позволяет указать исключения непосредственно в операторе CREATE TABLE. Поддерживается только в режиме RT.
Значения должны быть разделены точкой с запятой (;). Поскольку исключения могут содержать > или => в качестве разделителей и, возможно, другие специальные символы, убедитесь, что экранируете точки с запятой, если они являются частью самой формы (например, \;).
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
CREATE TABLE products(title text, price float) exceptions_list = 'at & t => at&t; MS Windows => ms windows'POST /cli -d "
CREATE TABLE products(title text, price float) exceptions_list = 'at & t => at&t; MS Windows => ms windows'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'exceptions_list' => 'at & t => at&t; MS Windows => ms windows'
]);utilsApi.sql('CREATE TABLE products(title text, price float) exceptions_list = \'at & t => at&t; MS Windows => ms windows\'')await utilsApi.sql('CREATE TABLE products(title text, price float) exceptions_list = \'at & t => at&t; MS Windows => ms windows\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) exceptions_list = \'at & t => at&t; MS Windows => ms windows\'');utilsApi.sql("CREATE TABLE products(title text, price float) exceptions_list = 'at & t => at&t; MS Windows => ms windows'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) exceptions_list = 'at & t => at&t; MS Windows => ms windows'", true);utils_api.sql("CREATE TABLE products(title text, price float) exceptions_list = 'at & t => at&t; MS Windows => ms windows'", Some(true)).await;