Когда текст индексируется в 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.
Подробнее о regexp_filter можно узнать здесь.
# 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, _
# override the default transliteration to preserve German umlauts and sharp s;
# uppercase variants are mapped to lowercase
charset_table = non_cont, german
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
}Помимо описаний символов и сопоставлений, доступны несколько встроенных псевдонимов. Текущие псевдонимы:
chinesecjkcontenglishgermanjapanesekoreannon_cont(non_cjk)russianthai
Псевдоним german сохраняет ä, ö, ü и ß вместо сопоставления их с ASCII-символами и приводит их заглавные варианты к строчным, включая ẞ в ß. Добавьте его после non_cont, как показано выше, чтобы сохранить остальные стандартные сопоставления символов.
- 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 list, поддерживаются по умолчанию.
Чтобы работать и с cont-, и с non-cont-языками, задайте параметры в файле конфигурации, как показано ниже (с исключением для китайского языка):
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) charset_table = 'non_cont' ngram_len = '1' ngram_chars = 'cont'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'
]);utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'non_cont\' ngram_len = \'1\' ngram_chars = \'cont\'')await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'non_cont\' ngram_len = \'1\' ngram_chars = \'cont\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'non_cont\' ngram_len = \'1\' ngram_chars = \'cont\'');utilsApi.sql("CREATE TABLE products(title text, price float) charset_table = 'non_cont' ngram_len = '1' ngram_chars = 'cont'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) charset_table = 'non_cont' ngram_len = '1' ngram_chars = 'cont'", true);utils_api.sql("CREATE TABLE products(title text, price float) charset_table = 'non_cont' ngram_len = '1' ngram_chars = 'cont'", Some(true)).await;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 и 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 с эквивалентными глифами.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) blend_chars = '+, &, U+23, @->_'POST /cli -d "
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, @->_'
]);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;table products {
blend_chars = +, &, U+23, @->_
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}blend_mode = option [, option [, ...]]
option = trim_none | trim_head | trim_tail | trim_both | trim_all | skip_pure
Режим индексирования смешанных токенов включается директивой blend_mode.
По умолчанию токены, в которых смешиваются смешиваемые и несмешиваемые символы, индексируются целиком. Например, если и символ @, и восклицательный знак входят в blend_chars, строка @dude! будет проиндексирована как два токена: @dude! (со всеми смешиваемыми символами) и dude (без них). В результате запрос @dude не будет с ним совпадать.
blend_mode добавляет гибкость этому поведению индексации. Он принимает список опций, разделённых запятыми, и каждая из них задаёт вариант индексирования токена.
Если указано несколько опций, будут проиндексированы несколько вариантов одного и того же токена. Обычные ключевые слова (полученные из этого токена заменой смешиваемых символов разделителем) всегда индексируются.
Варианты такие:
trim_none- индексировать весь токенtrim_head- обрезать смешиваемые символы в начале и индексировать получившийся токенtrim_tail- обрезать смешиваемые символы в конце и индексировать получившийся токенtrim_both- обрезать смешиваемые символы и в начале, и в конце и индексировать получившийся токенtrim_all- обрезать смешиваемые символы в начале, в конце и в середине и индексировать получившийся токенskip_pure- не индексировать токен, если он полностью состоит из смешиваемых символов
Если использовать blend_mode с примером строки @dude! выше, настройка blend_mode = trim_head, trim_tail приведёт к двум проиндексированным токенам: @dude и dude!. Использование trim_both не даст эффекта, потому что при обрезке обоих смешиваемых символов получится dude, а он уже индексируется как обычное ключевое слово. Индексирование @U.S.A. с trim_both (и при условии, что точка тоже смешиваемый символ) приведёт к индексации U.S.A. Наконец, skip_pure позволяет игнорировать только последовательности смешиваемых символов. Например, one @@@ two будет проиндексировано как one two, и это будет найдено как фраза. По умолчанию это не так, потому что полностью смешанный токен индексируется и смещает вторую позицию ключевого слова.
Поведение по умолчанию - индексировать весь токен, что эквивалентно blend_mode = trim_none.
Имейте в виду, что использование режимов смешивания ограничивает поиск, даже в режиме по умолчанию trim_none, если вы считаете . смешиваемым символом:
.dog.при индексации станет.dog. dog- и вы не сможете найти его по
dog..
Использование большего числа режимов повышает шанс, что ваше ключевое слово что-то совпадёт.
- 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 = '+, &'POST /cli -d "
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' => '+, &'
]);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;table products {
blend_mode = trim_tail, skip_pure
blend_chars = +, &
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}min_word_len = length
min_word_len — необязательный параметр конфигурации индекса в Manticore, который задаёт минимальную длину индексируемого слова. Значение по умолчанию — 1, что означает, что индексируется всё.
Будут индексироваться только те слова, длина которых не меньше этого минимума. Например, если min_word_len равен 4, то 'the' не будет проиндексировано, а 'they' будет.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) min_word_len = '4'POST /cli -d "
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'
]);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;table products {
min_word_len = 4
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}ngram_len = 1
Длины N-грамм для индексирования N-грамм. Необязательный, по умолчанию 0 (индексирование N-грамм отключено). Известные значения: 0 и 1.
N-граммы обеспечивают базовую поддержку языков с непрерывным письмом в неразделённых текстах. Проблема поиска в таких языках в том, что между словами нет чётких разделителей. В некоторых случаях может не понадобиться сегментация на основе словаря, например та, что доступна для китайского языка. В таких случаях сегментация на N-граммы тоже может хорошо работать.
Когда эта функция включена, последовательности таких языков (или любых других символов, заданных в ngram_chars) индексируются как N-граммы. Например, если входной текст — "ABCDEF" (где A to F обозначают некоторые символы языка) и ngram_len равен 1, он будет проиндексирован так, как будто это "A B C D E F". Сейчас поддерживается только ngram_len=1. Только те символы, которые перечислены в таблице ngram_chars, будут разделены таким образом; остальные затронуты не будут.
Обратите внимание: если поисковый запрос уже сегментирован, то есть между отдельными словами есть разделители, то заключение слов в кавычки и использование расширенного режима приведёт к корректному совпадению, даже если текст не был сегментирован. Например, если исходный запрос — BC DEF, после обрамления кавычками на стороне приложения он должен выглядеть как "BC" "DEF" (с кавычками). Этот запрос будет передан в Manticore и внутренне тоже разобьётся на 1-граммы, в результате чего получится запрос "B C" "D E F", всё ещё с кавычками, которые являются оператором поиска фразы. И он совпадёт с текстом, даже если в тексте не было разделителей.
Даже если поисковый запрос не сегментирован, Manticore всё равно должна выдавать хорошие результаты благодаря ранжированию по фразам: она будет поднимать выше более близкие фразовые совпадения (что в случае N-грамм может означать более близкие многосимвольные совпадения).
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) ngram_chars = 'cont' ngram_len = '1'POST /cli -d "
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'
]);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;table products {
ngram_chars = cont
ngram_len = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}ngram_chars = cont
ngram_chars = cont, U+3000..U+2FA1F
Список символов N-грамм. Необязательный, по умолчанию пуст.
Используется вместе с ngram_len и задаёт символы, последовательности которых подлежат извлечению N-грамм. Слова, состоящие из других символов, не будут затронуты функцией индексирования N-грамм. Формат значения идентичен charset_table. Символы N-грамм не могут присутствовать в charset_table.
- 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'POST /cli -d "
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'
]);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;table products {
ngram_chars = U+3000..U+2FA1F
ngram_len = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}Также вы можете использовать псевдоним для нашей таблицы N-грамм по умолчанию, как в примере. В большинстве случаев этого должно быть достаточно.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) ngram_chars = 'cont' ngram_len = '1'POST /cli -d "
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'
]);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;table products {
ngram_chars = cont
ngram_len = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}ignore_chars = U+AD
Список игнорируемых символов. Необязательный, по умолчанию пуст.
Полезно в случаях, когда некоторые символы, например мягкий знак переноса (U+00AD), должны не просто считаться разделителями, а полностью игнорироваться. Например, если '-' просто отсутствует в charset_table, текст "abc-def" будет проиндексирован как ключевые слова "abc" и "def". Напротив, если '-' добавить в список ignore_chars, тот же текст будет проиндексирован как одно ключевое слово "abcdef".
Синтаксис такой же, как у charset_table, но разрешено только объявлять символы, а не сопоставлять их. Кроме того, игнорируемые символы не должны присутствовать в charset_table.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) ignore_chars = 'U+AD'POST /cli -d "
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'
]);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;table products {
ignore_chars = U+AD
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}bigram_index = {none|all|first_freq|both_freq|second_numeric|second_has_digit}
Режим индексирования биграмм. Необязательный, по умолчанию none.
Индексирование биграмм - это функция ускорения фразового поиска. При индексации она сохраняет список документов для всех или некоторых пар соседних слов в индексе. Такой список затем можно использовать во время поиска, чтобы значительно ускорить совпадение фраз или подфраз.
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" (самая слабая из них с точки зрения поиска), а остальные пары слов - нет.second_numeric, индексировать только те пары слов, где второй токен состоит только из ASCII-цифр. Например,xt 806совпадает, аxt rt9600иxt v2- нет.second_has_digit, индексировать только те пары слов, где второй токен содержит хотя бы одну ASCII-цифру. Например,xt 806,xt rt9600иxt v2совпадают, аxt abc- нет.
Для большинства сценариев both_freq будет лучшим режимом, но результат может отличаться в зависимости от задачи.
Важно отметить, что bigram_index работает только на уровне токенизации и не учитывает преобразования вроде morphology, wordforms или stopwords. Это означает, что создаваемые им токены очень прямолинейны, что делает поиск фраз более точным и строгим. Хотя это может повысить точность фразового совпадения, система также становится менее способной распознавать разные формы слов или варианты их написания.
Числовые режимы используют только ASCII-цифры (0-9). Они не считают +, - или цифры Unicode числовыми. Проверки также используют текст токена, полученный текущим путём токенизации, без какой-либо дополнительной нормализации знаков препинания.
Используйте bigram_delimiter, чтобы управлять тем, хранится ли допустимая биграмма как внутренний токен с разделителем, как склеенный токен вроде iphone17 или в обоих видах.
- 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'POST /cli -d "
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'
]);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;table products {
bigram_index = both_freq
bigram_freq_words = the, a, you, i
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}bigram_delimiter = {true|none|both}
Режим хранения биграммных токенов. Необязательный, по умолчанию true.
bigram_delimiter управляет тем, какая форма токена сохраняется для допустимых биграмм, выбранных bigram_index:
true, сохранять только внутренний биграммный токен с разделителем. Это текущее поведение по умолчанию.none, сохранять только склеенную форму токена, напримерiphone17.both, сохранять и внутреннюю форму с разделителем, и склеенную форму.
Поведение поиска зависит от выбранного режима:
- при
trueоптимизация фраз переписывает допустимые пары фраз во внутренний токен с разделителем - при
noneоптимизация фраз переписывает допустимые пары фраз в склеенный токен, например"iphone 17"превращается вiphone17 - при
bothоптимизация фраз пропускается, и фразовые запросы остаются обычными фразовыми запросами, при этом поиск по склеенному токену всё равно может совпасть, потому что склеенная форма тоже хранится
bigram_delimiter меняет только форму хранимого токена. Он не определяет, какие пары допустимы; это по-прежнему задаётся bigram_index.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) bigram_index = 'all' bigram_delimiter = 'none'POST /cli -d "
CREATE TABLE products(title text, price float) bigram_index = 'all' bigram_delimiter = 'none'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'bigram_index' => 'all',
'bigram_delimiter' => 'none'
]);utilsApi.sql('CREATE TABLE products(title text, price float) bigram_index = \'all\' bigram_delimiter = \'none\'')await utilsApi.sql('CREATE TABLE products(title text, price float) bigram_index = \'all\' bigram_delimiter = \'none\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) bigram_index = \'all\' bigram_delimiter = \'none\'');utilsApi.sql("CREATE TABLE products(title text, price float) bigram_index = 'all' bigram_delimiter = 'none'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) bigram_index = 'all' bigram_delimiter = 'none'", true);utils_api.sql("CREATE TABLE products(title text, price float) bigram_index = 'all' bigram_delimiter = 'none'", Some(true)).await;table products {
bigram_index = all
bigram_delimiter = none
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}bigram_freq_words = the, a, you, i
Список ключевых слов, считающихся "частотными" при индексировании биграмм. Необязательный, по умолчанию пуст.
Некоторые режимы индексирования биграмм (см. bigram_index) требуют списка частотных ключевых слов. Их не следует путать со стоп-словами. Стоп-слова полностью удаляются и при индексации, и при поиске. Частотные ключевые слова используются только биграммами, чтобы определить, следует индексировать текущую пару слов или нет.
bigram_freq_words позволяет задать такой список ключевых слов.
Эта опция нужна только для first_freq и both_freq.
Она должна оставаться пустой для:
noneallsecond_numericsecond_has_digit
- 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'POST /cli -d "
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'
]);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;table products {
bigram_freq_words = the, a, you, i
bigram_index = first_freq
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}dict = {keywords|keywords_32k|crc}
Тип словаря определяется одним из трёх известных значений: keywords, keywords_32k или crc. Эта настройка необязательна; по умолчанию используется keywords.
dict=keywords и dict=keywords_32k - это словарные режимы. Словарный режим хранит исходный текст ключевого слова в индексе и выполняет расширение подстановочных шаблонов во время поиска. dict=crc вместо этого хранит контрольные суммы ключевых слов.
dict=keywords - это словарный режим по умолчанию.
dict=keywords_32k - это включаемый режим словаря для токенов ключевых слов размером до 32 КиБ. Он поддерживает нормализованные токены размером до 32768 байт как в обычных, так и в RT-таблицах. Токены, превышающие этот предел, пропускаются с предупреждением вместо того, чтобы индексироваться как обрезанные термины. Поддерживаются точный поиск, поиск по префиксу и поиск по инфиксу, если включены обычные настройки точного, префиксного или инфиксного поиска. Подробности о лимите обычного токена в 42 байта и лимите keywords_32k в 32768 байт см. в разделе Ограничение длины токена.
keywords_32k предназначен для длинных машинно сгенерированных значений, таких как хэши, сгенерированные идентификаторы, идентификаторы сообщений и длинные токены, похожие на адреса электронной почты.
Следующие функции пока не поддерживают dict=keywords_32k:
CALL SUGGESTиCALL QSUGGESTне работают с таблицами, использующимиdict=keywords_32k.- Percolate-таблицы не могут использовать
dict=keywords_32k. - Сниппеты и подсветка по-прежнему используют обычный лимит токенов. Токены длиной до 42 байт могут быть подсвечены; более длинные токены
keywords_32kпропускаются при обработке сниппетов и подсветки. indextool --dumpdictпока не может выгружать словариdict=keywords_32k.
CRC-словарь не хранит исходный текст ключевого слова в индексе. Вместо этого он заменяет ключевые слова значением контрольной суммы (вычисленным с помощью FNV64) как при поиске, так и при индексации. Это значение используется внутри индекса. У такого подхода есть два недостатка:
- Во-первых, существует риск столкновения контрольных сумм у разных пар ключевых слов. Этот риск растёт пропорционально числу уникальных ключевых слов в индексе. Тем не менее это незначительная проблема, поскольку вероятность одного столкновения FNV64 в словаре из 1 миллиарда записей составляет примерно 1 к 16, то есть 6,25%. Большинство словарей будут содержать гораздо меньше миллиарда ключевых слов, учитывая, что в типичном разговорном человеческом языке бывает от 1 до 10 миллионов словоформ.
- Во-вторых, и что важнее, с контрольными суммами не так просто выполнять поиски подстрок. Manticore решила эту проблему, предварительно индексируя все возможные подстроки как отдельные ключевые слова (см. директивы min_prefix_len, min_infix_len). У этого метода есть даже дополнительное преимущество: подстроки совпадают максимально быстро. Однако предварительная индексация всех подстрок значительно увеличивает размер индекса (часто в 3-10 раз и более), а затем влияет и на время индексации, делая поиск подстрок по большим индексам довольно непрактичным.
Словарный режим решает обе эти проблемы. Он хранит ключевые слова в индексе и выполняет расширение подстановочных шаблонов во время поиска. Например, поиск префикса test* может внутренне расшириться в запрос 'test|tests|testing' на основе содержимого словаря. Этот процесс расширения полностью прозрачен для приложения, за исключением того, что теперь также возвращается отдельная статистика по каждому совпавшему ключевому слову.
Для поиска подстрок (инфиксов) можно использовать расширенные подстановки. Специальные символы, такие как ? и %, совместимы с поиском подстрок (инфиксов) (например, t?st*, run%, *abc*). Обратите внимание, что операторы подстановок работают с dict=keywords и dict=keywords_32k, тогда как оператор REGEX работает только с dict=keywords.
Для токенов обычного размера индексирование со словарным режимом примерно в 1,1-1,3 раза медленнее, чем обычная индексация без подстрок, но значительно быстрее, чем индексирование подстрок (как префиксное, так и инфиксное). Размер индекса должен быть лишь немного больше, чем у стандартной таблицы без подстрок, с общей разницей в 1..10%. Время обычного поиска по ключевым словам должно быть почти одинаковым или идентичным для всех трёх рассматриваемых типов индекса (CRC без подстрок, CRC с подстроками, словарный режим). Время поиска подстрок может значительно меняться в зависимости от того, сколько реальных ключевых слов совпадает с данной подстрокой (то есть во сколько ключевых слов расширяется поисковый термин). Максимальное число совпавших ключевых слов ограничено директивой expansion_limit.
Итог такой: словарный и CRC-режимы предлагают два разных компромисса для поиска подстрок. Можно пожертвовать временем индексации и размером индекса, чтобы получить максимально быстрый поиск в худшем случае (CRC-словарь), либо минимально влиять на время индексации, но пожертвовать временем поиска в худшем случае, когда префикс расширяется в большое число ключевых слов (словарйный режим).
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) dict = 'keywords'POST /cli -d "
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'
]);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;table products {
dict = keywords
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}embedded_limit = size
Ограничение размера встроенных файлов exceptions, wordforms или stop words. Необязательный, по умолчанию 16K.
При создании таблицы указанные выше файлы можно либо сохранить отдельно вместе с таблицей, либо встроить непосредственно в таблицу. Файлы размером меньше embedded_limit сохраняются в таблице. Для более крупных файлов сохраняются только имена файлов. Это также упрощает перенос файлов таблицы на другой сервер: иногда достаточно скопировать один файл.
Для небольших файлов такое встраивание уменьшает число внешних файлов, от которых зависит таблица, и упрощает сопровождение. Но в то же время нет смысла встраивать словарь wordforms размером 100 МБ в маленькую delta-таблицу. Поэтому нужен порог по размеру, и embedded_limit - это как раз такой порог.
- CONFIG
table products {
embedded_limit = 32K
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}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.
Вы можете собрать .idf-файл с помощью утилиты indextool, сначала выгрузив словари с помощью ключа --dumpdict dict.txt --stats, затем преобразовав их в формат .idf с помощью --buildidf, а потом объединив все .idf-файлы по кластеру с помощью --mergeidf.
- 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'POST /cli -d "
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'
]);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;table products {
global_idf = /usr/local/manticore/var/global.idf
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}hitless_words = {all|path/to/file}
Список hitless-слов. Необязательный, допустимые значения: 'all' или имя файла со списком.
По умолчанию полнотекстовый индекс Manticore хранит не только список совпадающих документов для каждого заданного ключевого слова, но и список его позиций внутри документа (так называемый hitlist). Hitlist'ы позволяют выполнять поиск по фразам, по близости, в строгом порядке и другие расширенные типы поиска, а также ранжирование по близости фраз. Однако hitlist'ы для отдельных частотных ключевых слов (которые по какой-то причине нельзя исключить, несмотря на их частоту) могут стать очень большими и, следовательно, медленными в обработке при поиске. Кроме того, в некоторых случаях нам может быть нужен только булев поиск по ключевым словам, и тогда позиционные операторы поиска (такие как поиск по фразе) или ранжирование по фразам вообще не нужны.
hitless_words позволяет создавать индексы, которые либо вообще не содержат позиционной информации (hitlist'ов), либо не хранят её для отдельных ключевых слов.
Hitless-индекс обычно занимает меньше места, чем соответствующий обычный полнотекстовый индекс (можно ожидать примерно в 1,5 раза меньший размер). И индексация, и поиск должны быть быстрее, но ценой отсутствия поддержки позиционных запросов и ранжирования.
Если такие слова используются в позиционных запросах (например, в запросах по фразам), они удаляются из них и используются как операнд без позиции. Например, если "hello" и "world" являются hitless, а "simon" и "says" - нет, то фразовый запрос "simon says hello world" будет преобразован в ("simon says" & hello & world), где "hello" и "world" будут совпадать в любом месте документа, а "simon says" - как точная фраза.
Если позиционный запрос содержит только hitless-слова, в результате получится пустой узел фразы, поэтому весь запрос вернёт пустой результат и предупреждение. Если весь словарь hitless (используется all), на соответствующем индексе можно использовать только булев поиск.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) hitless_words = 'all'POST /cli -d "
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'
]);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;table products {
hitless_words = all
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}hitless_words_list = 'word1; word2; ...'
Параметр hitless_words_list позволяет указать hitless-слова прямо в операторе CREATE TABLE. Он поддерживается только в RT-режиме.
Значения должны быть разделены точками с запятой (;).
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
CREATE TABLE products(title text, price float) hitless_words_list = 'hello; world'POST /cli -d "
CREATE TABLE products(title text, price float) hitless_words_list = 'hello; world'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'hitless_words_list' => 'hello; world'
]);utilsApi.sql('CREATE TABLE products(title text, price float) hitless_words_list = \'hello; world\'')await utilsApi.sql('CREATE TABLE products(title text, price float) hitless_words_list = \'hello; world\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) hitless_words_list = \'hello; world\'');utilsApi.sql("CREATE TABLE products(title text, price float) hitless_words_list = 'hello; world'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) hitless_words_list = 'hello; world'", true);utils_api.sql("CREATE TABLE products(title text, price float) hitless_words_list = 'hello; world'", Some(true)).await;index_field_lengths = {0|1}
Включает вычисление и сохранение длин полей (как по документам, так и средних значений по индексу) в полнотекстовом индексе. Необязательный, по умолчанию 0 (не вычислять и не сохранять).
Когда index_field_lengths установлен в 1, Manticore будет:
- создавать соответствующий атрибут длины для каждого полнотекстового поля с тем же именем, но с суффиксом
__len - вычислять длину поля (считая в ключевых словах) для каждого документа и сохранять её в соответствующий атрибут
- вычислять средние значения по индексу. Атрибуты длины будут иметь специальный тип TOKENCOUNT, но на самом деле их значения - обычные 32-битные целые числа, и к ним обычно можно обращаться напрямую.
Функции BM25A() и BM25F() в ранжировщике expressions основаны на этих длинах и требуют включённого index_field_lengths. Исторически Manticore использовала упрощённый, облегчённый вариант BM25, который, в отличие от полной функции, не учитывал длину документа. Также поддерживаются полная версия BM25 и её расширение для нескольких полей, называемое BM25F. Они требуют соответственно длины по документу и длины по полям. Отсюда и дополнительная директива.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) index_field_lengths = '1'POST /cli -d "
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'
]);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;table products {
index_field_lengths = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}index_token_filter = my_lib.so:custom_blend:chars=@#&
Фильтр токенов на этапе индексации для полнотекстовой индексации. Необязательный, по умолчанию пуст.
Директива index_token_filter задаёт необязательный фильтр токенов на этапе индексации для полнотекстовой индексации. Эта директива используется для создания пользовательского токенизатора, который формирует токены по пользовательским правилам. Фильтр создаётся indexer'ом при индексации исходных данных в обычную таблицу или RT-таблицей при обработке операторов INSERT или REPLACE. Плагины задаются в формате library name:plugin name:optional string of settings. Например, my_lib.so:custom_blend:chars=@#&.
- 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=@#&'POST /cli -d "
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=@#&'
]);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;table products {
index_token_filter = my_lib.so:custom_blend:chars=@#&
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}overshort_step = {0|1}
Приращение позиции для слишком коротких ключевых слов (короче min_word_len). Необязательный, допустимые значения: 0 и 1, по умолчанию 1.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) overshort_step = '1'POST /cli -d "
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'
]);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;table products {
overshort_step = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}phrase_boundary = ., ?, !, U+2026 # horizontal ellipsis
Список символов границ фразы. Необязательный, по умолчанию пуст.
Этот список управляет тем, какие символы будут считаться границами фразы, чтобы корректировать позиции слов и обеспечивать эмуляцию поиска на уровне фраз через поиск по близости. Синтаксис похож на charset_table, но сопоставления не допускаются, а символы границ не должны пересекаться с чем-либо ещё.
На границе фразы к текущей позиции слова будет добавлено дополнительное приращение позиции (указывается параметром phrase_boundary_step). Это позволяет выполнять поиск на уровне фраз через запросы по близости: слова из разных фраз гарантированно будут находиться друг от друга на расстоянии больше phrase_boundary_step; поэтому поиск по близости в пределах этого расстояния будет эквивалентен поиску по фразе.
Условие границы фразы будет срабатывать тогда и только тогда, когда за таким символом следует разделитель; это нужно, чтобы сокращения вроде S.T.A.L.K.E.R или URL не воспринимались как несколько фраз.
- 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'POST /cli -d "
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'
]);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;table products {
phrase_boundary = ., ?, !, U+2026
phrase_boundary_step = 10
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}phrase_boundary_step = 100
Приращение позиции слова на границе фразы. Необязательный, по умолчанию 0.
На границе фразы текущая позиция слова будет дополнительно увеличена на это число.
- 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'POST /cli -d "
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'
]);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;table products {
phrase_boundary_step = 100
phrase_boundary = ., ?, !, U+2026
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}# 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.
В некоторых сценариях, например при поиске товаров, один и тот же продукт, модель или свойство можно называть по-разному. Например, iPhone 3gs и iPhone 3 gs (или даже iPhone3 gs) очень вероятно относятся к одному и тому же продукту. Другой пример - разные способы указать размер экрана ноутбука, такие как 13-inch, 13 inch, 13" или 13in.
Регулярные выражения позволяют задавать правила, специально рассчитанные на такие случаи. В первом примере можно было бы использовать файл wordforms, чтобы обработать несколько моделей iPhone, но во втором лучше задать правила, которые нормализуют "13-inch" и "13in" к одному и тому же виду.
Регулярные выражения, перечисленные в regexp_filter, применяются в том порядке, в котором они указаны, на самой ранней возможной стадии, до любой другой обработки (включая exceptions), даже до токенизации. То есть регулярные выражения применяются к сырым исходным полям при индексации и к сырую тексту поискового запроса при поиске.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) regexp_filter = '(blue|red) => color'POST /cli -d "
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'
]);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;table products {
# 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
}Поиск с подстановочными знаками (wildcard) — это распространенный тип текстового поиска. В Manticore он выполняется на уровне словаря. По умолчанию как обычные таблицы, так и RT-таблицы используют тип словаря под названием dict. В этом режиме слова хранятся как есть, поэтому включение поиска с подстановочными знаками не влияет на размер таблицы. При выполнении такого поиска словарь просматривается, чтобы найти все возможные варианты раскрытия слова с подстановочным знаком. Это раскрытие может быть проблематичным с точки зрения вычислительных затрат в момент выполнения запроса, когда раскрываемое слово дает много вариантов или варианты имеют огромные списки совпадений (hitlists), особенно в случае инфиксов, когда подстановочный знак добавляется в начало и конец слова. Чтобы избежать таких проблем, можно использовать expansion_limit.
ПРИМЕЧАНИЕ: Изменение настроек wildcard на этапе индексации, таких как
min_prefix_lenилиmin_infix_len, в уже заполненной таблице влияет только на документы, проиндексированные после изменения. Чтобы применить новые настройки к существующим документам, переиндексируйте их.
min_prefix_len = length
Эта настройка определяет минимальную длину префикса слова для индексации и поиска. По умолчанию установлено значение 0, что означает, что префиксы не разрешены.
Префиксы позволяют выполнять поиск с подстановочными знаками с помощью шаблонов вида началослова*.
Например, если слово "example" проиндексировано с min_prefix_len=3, его можно найти, выполнив поиск по "exa", "exam", "examp", "exampl", а также по полному слову.
Обратите внимание, что при использовании dict=crc параметр min_prefix_len повлияет на размер полнотекстового индекса, поскольку каждое раскрытие слова будет храниться дополнительно.
Manticore может различать точные совпадения слов и совпадения по префиксу и ранжировать первые выше, если выполняются следующие условия:
- dict=keywords (по умолчанию включено) или dict=keywords_32k
- 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 (по умолчанию включено) или dict=keywords_32k
- 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 или dict=keywords_32k, помимо подстановочного знака *, можно использовать еще два символа подстановки:
?может соответствовать любому (одному) символу: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=crc.
По умолчанию индексирование подстрок в dict=crc индексирует все возможные подстроки как отдельные ключевые слова, что может привести к чрезмерно большому полнотекстовому индексу. Поэтому директива 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 или dict=keywords_32k индексирование подстрок выполняется словарем слов, а не за счет предварительного индексирования CRC-подстрок. Поэтому эта директива неприменима и в таком случае намеренно запрещена. Однако при необходимости вы все равно можете ограничить длину подстроки, которую ищете, в коде приложения.
- 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
- JSON
- Config
create table tbl1 ... wordforms='/tmp/wf*'
create table tbl2 ... wordforms='/tmp/wf, /tmp/wf2'POST /sql?mode=raw -d "create table tbl1 ... wordforms='/tmp/wf*'"
POST /sql?mode=raw -d "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;