Manticore предоставляет встроенную поддержку для индексации языков с непрерывным письмом (т.е. языков, которые не используют пробелы или другие знаки между словами или предложениями). Это позволяет обрабатывать тексты на этих языках двумя различными способами:
- Точная сегментация с использованием библиотеки ICU. В настоящее время поддерживается только китайский язык.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- Javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) charset_table = 'cont' morphology = 'icu_chinese'POST /cli -d "
CREATE TABLE products(title text, price float) charset_table = 'cont' morphology = 'icu_chinese'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'charset_table' => 'cont',
'morphology' => 'icu_chinese'
]);utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'cont\' morphology = \'icu_chinese\'')await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'cont\' morphology = \'icu_chinese\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'cont\' morphology = \'icu_chinese\'');utilsApi.sql("CREATE TABLE products(title text, price float) charset_table = 'cont' morphology = 'icu_chinese'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) charset_table = 'cont' morphology = 'icu_chinese'", true);utils_api.sql("CREATE TABLE products(title text, price float) charset_table = 'cont' morphology = 'icu_chinese'", Some(true)).await;table products {
charset_table = cont
morphology = icu_chinese
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}- Точная сегментация с использованием библиотеки Jieba. Как и ICU, в настоящее время поддерживает только китайский язык.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- Javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) charset_table = 'cont' morphology = 'jieba_chinese'POST /cli -d "
CREATE TABLE products(title text, price float) charset_table = 'cont' morphology = 'jieba_chinese'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'charset_table' => 'cont',
'morphology' => 'jieba_chinese'
]);utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'cont\' morphology = \'jieba_chinese\'')await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'cont\' morphology = \'jieba_chinese\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'cont\' morphology = \'jieba_chinese\'');utilsApi.sql("CREATE TABLE products(title text, price float) charset_table = 'cont' morphology = 'jieba_chinese'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) charset_table = 'cont' morphology = 'jieba_chinese'", true);utils_api.sql("CREATE TABLE products(title text, price float) charset_table = 'cont' morphology = 'jieba_chinese'", Some(true)).await;table products {
charset_table = cont
morphology = jieba_chinese
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}- Базовая поддержка с использованием опций N-gram ngram_len и ngram_chars
Для каждого языка, использующего непрерывное письмо, существуют отдельные таблицы наборов символов (
chinese,korean,japanese,thai), которые можно использовать. В качестве альтернативы, вы можете использовать общую таблицу наборов символовcontдля поддержки всех языков CJK и тайского одновременно, или набор символовcjkдля включения только всех языков CJK.
- 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'
/* Or, alternatively */
CREATE TABLE products(title text, price float) charset_table = 'non_cont' ngram_len = '1' ngram_chars = 'cjk,thai'POST /cli -d "
CREATE TABLE products(title text, price float) charset_table = 'non_cont' ngram_len = '1' ngram_chars = 'cont'"
/* Or, alternatively */
POST /cli -d "
CREATE TABLE products(title text, price float) charset_table = 'non_cont' ngram_len = '1' ngram_chars = 'cjk,thai'"$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
}Кроме того, существует встроенная поддержка китайских стоп-слов с псевдонимом zh.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) charset_table = 'chinese' morphology = 'icu_chinese' stopwords = 'zh'POST /cli -d "
CREATE TABLE products(title text, price float) charset_table = 'chinese' morphology = 'icu_chinese' stopwords = 'zh'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'charset_table' => 'chinese',
'morphology' => 'icu_chinese',
'stopwords' => 'zh'
]);utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'chinese\' morphology = \'icu_chinese\' stopwords = \'zh\'')await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'chinese\' morphology = \'icu_chinese\' stopwords = \'zh\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'chinese\' morphology = \'icu_chinese\' stopwords = \'zh\'');utilsApi.sql("CREATE TABLE products(title text, price float) charset_table = 'chinese' morphology = 'icu_chinese' stopwords = 'zh'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) charset_table = 'chinese' morphology = 'icu_chinese' stopwords = 'zh'", true);utils_api.sql("CREATE TABLE products(title text, price float) charset_table = 'chinese' morphology = 'icu_chinese' stopwords = 'zh'", Some(true)).await;table products {
charset_table = chinese
morphology = icu_chinese
stopwords = zh
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}Когда текст индексируется в 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, _
# you can override character mappings by redefining them, e.g. for case insensitive search with German umlauts you can use:
charset_table = non_cont, U+00E4, U+00C4->U+00E4, U+00F6, U+00D6->U+00F6, U+00FC, U+00DC->U+00FC, U+00DF, U+1E9E->U+00DF
charset_table задаёт массив, который сопоставляет буквенные символы с их версиями в приведённом к одному регистру виде (или с любыми другими символами, если вы предпочитаете). Набор символов по умолчанию — non_cont, который включает большинство языков с неконтинуальными сценариями письма.
charset_table является ключевым элементом процесса токенизации в Manticore, который извлекает ключевые слова из текста документа или текста запроса. Он контролирует, какие символы считаются допустимыми и как они должны преобразовываться (например, следует ли удалять регистр или нет).
По умолчанию каждый символ отображается в 0, что означает, что он не считается допустимым ключевым словом и обрабатывается как разделитель. Как только символ упоминается в таблице, он отображается в другой символ (чаще всего в себя самого или в строчную букву) и считается допустимой частью ключевого слова.
charset_table использует список отображений, разделённых запятыми, чтобы объявить символы допустимыми или сопоставить их с другими символами. Существуют сокращённые синтаксисы для сопоставления диапазонов символов сразу:
- Отображение одного символа:
A->a. Объявляет исходный символ 'A' допустимым в ключевых словах и сопоставляет его с символом назначения 'a' (но не объявляет 'a' как допустимый). - Отображение диапазона:
A..Z->a..z. Объявляет все символы из исходного диапазона допустимыми и сопоставляет их с соответствующими символами из целевого диапазона. Не объявляет целевой диапазон как допустимый. Проверяется равенство длины диапазонов. - Отображение одиночного символа:
a. Объявляет символ допустимым и сопоставляет его с самим собой. Эквивалентно отображению одного символаa->a. - Отображение одиночного диапазона:
a..z. Объявляет все символы в диапазоне допустимыми и сопоставляет их сами с собой. Эквивалентно отображению диапазонаa..z->a..z. - Отображение с шахматной доской:
A..Z/2. Сопоставляет каждую пару символов со вторым символом в паре. Например,A..Z/2эквивалентноA->B, B->B, C->D, D->D, ..., Y->Z, Z->Z. Этот сокращённый способ удобен для Unicode-блоков, где заглавные и прописные буквы чередуются.
Для символов с кодами от 0 до 32 и символов в диапазоне от 127 до 8-битного ASCII и Unicode символов, Manticore всегда рассматривает их как разделители. Чтобы избежать проблем с кодировкой файла конфигурации, 8-битные ASCII и Unicode символы должны указываться в форме U+XXX, где XXX — шестнадцатеричный номер кода символа. Минимальный допустимый код Unicode — U+0021.
Если стандартных отображений недостаточно, вы можете переопределить отображения символов, указав их заново с другим отображением. Например, если встроенный массив non_cont включает символы Ä и ä и сопоставляет их обоих с ASCII символом a, вы можете переопределить эти символы, добавив их Unicode-коды, так:
charset_table = non_cont,U+00E4,U+00C4
для чувствительного к регистру поиска или
charset_table = non_cont,U+00E4,U+00C4->U+00E4
для нечувствительного к регистру поиска.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) charset_table = '0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451'POST /cli -d "
CREATE TABLE products(title text, price float) charset_table = '0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'charset_table' => '0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451'
]);utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451\'')await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451\'');utilsApi.sql("CREATE TABLE products(title text, price float) charset_table = '0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) charset_table = '0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451'", true);utils_api.sql("CREATE TABLE products(title text, price float) charset_table = '0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451'", Some(true)).await;table products {
charset_table = 0..9, A..Z->a..z, _, a..z, \
U+410..U+42F->U+430..U+44F, U+430..U+44F, U+401->U+451, U+451
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}Помимо определений символов и отображений, имеются несколько встроенных псевдонимов, которые можно использовать. Текущие псевдонимы:
chinesecjkcontenglishjapanesekoreannon_cont(non_cjk)russianthai
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) charset_table = '0..9, english, _'POST /cli -d "
CREATE TABLE products(title text, price float) charset_table = '0..9, english, _'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'charset_table' => '0..9, english, _'
]);utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'0..9, english, _\'')await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'0..9, english, _\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) charset_table = \'0..9, english, _\'');utilsApi.sql("CREATE TABLE products(title text, price float) charset_table = '0..9, english, _'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) charset_table = '0..9, english, _'", true);utils_api.sql("CREATE TABLE products(title text, price float) charset_table = '0..9, english, _'", Some(true)).await;table products {
charset_table = 0..9, english, _
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}Если вы хотите поддерживать различные языки в вашем поиске, определение наборов допустимых символов и правил свертки для всех языков может оказаться трудоемкой задачей. Мы упростили эту задачу для вас, предоставив стандартные таблицы наборов символов, non_cont и cont, которые охватывают языки с неконтинуальными и континуальными (китайский, японский, корейский, тайский) системами письма соответственно. В большинстве случаев этих наборов должно быть достаточно для ваших нужд.
Обратите внимание, что следующие языки в настоящее время не поддерживаются:
- Ассамский
- Бишнуприя
- Бухид
- Гаро
- Хмонг
- Хо
- Коми
- Большой Цветочный Мяо
- Маба
- Майтхили
- Марати
- Менде
- Мру
- Мьене
- Нгамбай
- Одиа
- Сантали
- Синдхи
- Силхети
Все остальные языки, перечисленные в списке языков Unicode list, поддерживаются по умолчанию.
Чтобы работать с языками как с континуальным, так и с неконтинуальным письмом, установите опции в вашем конфигурационном файле, как показано ниже (с исключением для китайского):
- 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 будет индексироваться как some, something и thing с blend_mode = trim_all.
Следует соблюдать осторожность при использовании смешанных символов, так как определение символа как смешанного означает, что он больше не считается разделителем.
- Поэтому если добавить запятую в
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 (с учетом, что точка – смешанный символ 2-го типа) приведет к индексации 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–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}
Режим индексации биграмм. Необязательно, по умолчанию отсутствует.
Индексация биграмм — это функция для ускорения поиска фраз. При индексации она сохраняет список документов для всех или некоторых пар соседних слов в индексе. Такой список затем может использоваться во время поиска для значительного ускорения поиска фраз или их частей.
bigram_index управляет выбором конкретных пар слов. Известны следующие режимы:
all— индексировать каждую пару словfirst_freq— индексировать только пары слов, где первое слово находится в списке частотных слов (см. bigram_freq_words). Например, сbigram_freq_words = the, in, i, aпри индексации текста "alone in the dark" будут сохранены пары "in the" и "the dark" как биграммы, потому что они начинаются с частого слова ("in" или "the"), а "alone in" не будет индексирована, так как "in" — второе слово в паре.both_freq— индексировать только пары слов, где оба слова частотные. Продолжая тот же пример, в этом режиме при индексации "alone in the dark" будет сохранена только пара "in the" (самая плохая для поиска), остальные пары не будут индексированы.
Для большинства случаев лучший режим — both_freq, но всё зависит от ваших задач.
Важно отметить, что bigram_index работает только на уровне токенизации и не учитывает преобразования как morphology, wordforms или stopwords. Это означает, что создаваемые токены очень простые, что делает поиск фраз более точным и строгим. Хотя это может повысить точность фразового совпадения, система становится менее способной распознавать различные формы слов или вариации их появления.
- 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_freq_words = the, a, you, i
Список ключевых слов, считаемых "частотными" при индексировании биграмм. Необязательно, по умолчанию пусто.
Некоторые режимы индексирования биграмм (см. bigram_index) требуют определения списка частых ключевых слов. Их не следует путать со стоп-словами. Стоп-слова полностью исключаются как при индексировании, так и при поиске. Частые ключевые слова используются биграммами только для определения необходимости индексировать текущую пару слов или нет.
bigram_freq_words позволяет определить такой список ключевых слов.
- 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|crc}
Тип словаря ключевых слов определяется одним из двух известных значений: 'crc' или 'keywords'. Это опционально, по умолчанию используется 'keywords'.
Использование режима словаря ключевых слов (dict=keywords) может значительно снизить нагрузку индексирования и позволить выполнять поиск подстрок в крупных коллекциях. Этот режим может применяться как для обычных, так и для RT таблиц.
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*). Обратите внимание, что операторы подстановок и REGEX работают только с dict=keywords.
Индексирование с использованием словаря ключевых слов примерно в 1.1-1.3 раза медленнее обычного индексирования без подстрок — но существенно быстрее индексирования с подстроками (как префиксными, так и инфиксными). Размер индекса должен быть лишь немного больше, чем у стандартной таблицы без подстрок, с общей разницей от 1 до 10%. Время обычного поиска по ключевым словам должно быть почти одинаковым во всех трёх рассмотренных типах индексов (CRC без подстрок, CRC с подстроками, keywords). Время поиска подстрок может значительно варьироваться в зависимости от количества ключевых слов, совпадающих с данной подстрокой (то есть насколько сильно поисковый термин расширяется). Максимальное число совпадающих ключевых слов ограничено директивой 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
Лимит размера файла встроенных исключений, форм слов или стоп-слов. Опционально, по умолчанию 16К.
При создании таблицы указанные выше файлы могут сохраняться либо внешне вместе с таблицей, либо непосредственно в самой таблице. Файлы размером меньше embedded_limit сохраняются внутри таблицы. Для больших файлов сохраняются только имена файлов. Это также упрощает перенос файлов таблицы на другой компьютер; зачастую достаточно просто скопировать один файл.
При небольших файлах такое встраивание уменьшает количество внешних файлов, от которых зависит таблица, и упрощает поддержку. Но в то же время нет смысла встраивать словарь словоформ размером 100 МБ в крошечную дельта-таблицу. Поэтому необходим порог размера, и 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 могут использоваться совместно несколькими таблицами. Только одна копия файла IDF будет загружена searchd, даже если на этот файл ссылаются многие таблицы. Если содержимое файла 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}
Список слов без позиций. Необязательный параметр, допустимые значения: 'all' или имя файла со списком.
По умолчанию полнотекстовый индекс Manticore хранит не только список соответствующих документов для каждого заданного ключевого слова, но и список его позиций в документе (известный как хитлист). Хитлисты позволяют выполнять фразовый, proximity, строгий порядок и другие продвинутые типы поиска, а также ранжирование по близости фраз. Однако хитлисты для определенных частых ключевых слов (которые по какой-то причине не могут быть стоп-словами, несмотря на частоту) могут стать огромными и, следовательно, медленными при обработке запросов. Кроме того, в некоторых случаях нас может интересовать только булево соответствие ключевых слов, и нам никогда не понадобятся операторы поиска на основе позиций (такие как фразовый поиск) или ранжирование по фразам.
hitless_words позволяет создавать индексы, которые либо вообще не имеют позиционной информации (хитлистов), либо пропускают её для определенных ключевых слов.
Индекс без позиций обычно будет занимать меньше места, чем соответствующий обычный полнотекстовый индекс (можно ожидать примерно в 1,5 раза меньше). Индексирование и поиск должны быть быстрее, ценой потери поддержки позиционных запросов и ранжирования.
Если такие слова используются в позиционных запросах (например, фразовых запросах), они извлекаются из них и используются как операнд без позиции. Например, если "hello" и "world" являются словами без позиций, а "simon" и "says" — нет, то фразовый запрос "simon says hello world" будет преобразован в ("simon says" & hello & world), где "hello" и "world" могут находиться где угодно в документе, а "simon says" — как точная фраза.
Позиционный запрос, содержащий только слова без позиций, приведет к пустому фразовому узлу, поэтому весь запрос вернет пустой результат и предупреждение. Если весь словарь состоит из слов без позиций (используя 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 позволяет указать слова без позиций непосредственно в операторе 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() в ранкере выражений основаны на этих длинах и требуют включения 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 задаёт необязательный токенный фильтр на этапе индексации для полнотекстового индексирования. Эта директива используется для создания пользовательского токенизатора, который формирует токены в соответствии с пользовательскими правилами. Фильтр создаётся индексатором при индексации исходных данных в обычную таблицу или RT-таблицей при обработке операторов INSERT или REPLACE. Плагины определяются с использованием формата имя_библиотеки:имя_плагина:необязательная_строка_настроек. Например, 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
Регулярные выражения (regexp), используемые для фильтрации полей и запросов. Эта директива является необязательной, может иметь несколько значений, и по умолчанию представляет собой пустой список регулярных выражений. Движок регулярных выражений, используемый Manticore Search, — это RE2 от Google, известный своей скоростью и безопасностью. Подробную информацию о синтаксисе, поддерживаемом RE2, можно найти в руководстве по синтаксису RE2.
В некоторых приложениях, таких как поиск товаров, может быть множество способов обозначить продукт, модель или свойство. Например, iPhone 3gs и iPhone 3 gs (или даже iPhone3 gs) с высокой вероятностью относятся к одному и тому же продукту. Другой пример — различные способы указания размера экрана ноутбука, такие как 13-inch, 13 inch, 13" или 13in.
Регулярные выражения предоставляют механизм для задания правил, адаптированных для обработки таких случаев. В первом примере можно было бы использовать файл wordforms для обработки нескольких моделей iPhone, но во втором примере лучше задать правила, которые приведут "13-inch" и "13in" к чему-то идентичному.
Регулярные выражения, перечисленные в regexp_filter, применяются в том порядке, в котором они указаны, на максимально ранней стадии, до любой другой обработки (включая исключения), даже до токенизации. То есть, regexp применяются к исходным полям при индексации и к исходному тексту поискового запроса при поиске.
- 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.
min_prefix_len = length
Эта настройка определяет минимальную длину префикса слова для индексации и поиска. По умолчанию установлено значение 0, что означает, что префиксы не разрешены.
Префиксы позволяют выполнять поиск с подстановочными знаками с помощью шаблонов вида началослова*.
Например, если слово "example" проиндексировано с min_prefix_len=3, его можно найти, выполнив поиск по "exa", "exam", "examp", "exampl", а также по полному слову.
Обратите внимание, что при использовании dict=crc параметр min_prefix_len повлияет на размер полнотекстового индекса, поскольку каждое раскрытие слова будет храниться дополнительно.
Manticore может различать точные совпадения слов и совпадения по префиксу и ранжировать первые выше, если выполняются следующие условия:
- dict=keywords (включено по умолчанию)
- index_exact_words=1 (выключено по умолчанию),
- expand_keywords=1 (также выключено по умолчанию)
Обратите внимание, что в режиме dict=crc или при отключении любой из вышеуказанных опций невозможно различить префиксы и полные слова, и точные совпадения слов не могут быть ранжированы выше.
Когда минимальная длина инфикса установлена в положительное число, минимальная длина префикса всегда считается равной 1.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) min_prefix_len = '3'POST /cli -d "
CREATE TABLE products(title text, price float) min_prefix_len = '3'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'min_prefix_len' => '3'
]);utilsApi.sql('CREATE TABLE products(title text, price float) min_prefix_len = \'3\'')await utilsApi.sql('CREATE TABLE products(title text, price float) min_prefix_len = \'3\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) min_prefix_len = \'3\'');utilsApi.sql("CREATE TABLE products(title text, price float) min_prefix_len = '3'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) min_prefix_len = '3'", true);utils_api.sql("CREATE TABLE products(title text, price float) min_prefix_len = '3'", Some(true)).await;table products {
min_prefix_len = 3
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}min_infix_len = length
Настройка min_infix_len определяет минимальную длину инфиксного префикса для индексации и поиска. Она является необязательной, и ее значение по умолчанию равно 0, что означает, что инфиксы не разрешены. Минимально допустимое ненулевое значение — 2.
При включении инфиксы позволяют выполнять поиск с подстановочными знаками с шаблонами терминов, такими как начало*, *конец, *середина* и так далее. Это также позволяет отключать слишком короткие подстановочные знаки, если поиск по ним слишком затратен.
Если выполняются следующие условия, Manticore может различать точные совпадения слов и совпадения по инфиксу и ранжировать первые выше:
- dict=keywords (включено по умолчанию)
- index_exact_words=1 (выключено по умолчанию),
- expand_keywords=1 (также выключено по умолчанию)
Обратите внимание, что в режиме dict=crc или при отключении любой из вышеуказанных опций нет возможности различить инфиксы и полные слова, и, следовательно, точные совпадения слов не могут быть ранжированы выше.
Время выполнения запроса с инфиксным поиском с подстановочными знаками может сильно варьироваться в зависимости от того, на сколько ключевых слов фактически раскроется подстрока. Короткие и частые слоги, такие как *in* или *ti*, могут раскрыться в слишком много ключевых слов, все из которых необходимо сопоставить и обработать. Поэтому для общего включения поиска по подстрокам обычно устанавливают min_infix_len равным 2. Чтобы ограничить влияние поиска с подстановочными знаками с слишком короткими шаблонами, можно установить большее значение.
Инфиксы должны быть длиной не менее 2 символов, и подстановочные знаки вида *a* не разрешены по соображениям производительности.
Когда min_infix_len установлен в положительное число, минимальная длина префикса считается равной 1. Для dict инфиксирование и префиксирование слов не могут быть включены одновременно. Для dict и других полей, для которых префиксы объявлены с помощью prefix_fields, запрещено объявлять одно и то же поле в обоих списках.
Если dict=keywords, помимо подстановочного знака * можно использовать еще два других:
?может соответствовать любому (одному) символу:t?stсоответствуетtest, но неteast%может соответствовать нулю или одному символу:tes%соответствуетtesилиtest, но неtesting
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) min_infix_len = '3'POST /cli -d "
CREATE TABLE products(title text, price float) min_infix_len = '3'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'min_infix_len' => '3'
]);utilsApi.sql('CREATE TABLE products(title text, price float) min_infix_len = \'3\'')await utilsApi.sql('CREATE TABLE products(title text, price float) min_infix_len = \'3\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) min_infix_len = \'3\'');utilsApi.sql("CREATE TABLE products(title text, price float) min_infix_len = '3'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) min_infix_len = '3'", true);utils_api.sql("CREATE TABLE products(title text, price float) min_infix_len = '3'", Some(true)).await;table products {
min_infix_len = 3
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}prefix_fields = field1[, field2, ...]
Настройка prefix_fields используется для ограничения префиксного индексирования определенными полнотекстовыми полями в режиме dict=crc. По умолчанию все поля индексируются в префиксном режиме, но поскольку префиксное индексирование может влиять как на производительность индексации, так и на производительность поиска, может потребоваться ограничить его определенными полями.
Чтобы ограничить префиксное индексирование определенными полями, используйте настройку prefix_fields, за которой следует список имен полей, разделенных запятыми. Если prefix_fields не задана, то все поля будут индексироваться в префиксном режиме.
- CONFIG
table products {
prefix_fields = title, name
min_prefix_len = 3
dict = crcinfix_fields = field1[, field2, ...]
Настройка infix_fields позволяет указать список полнотекстовых полей, чтобы ограничить инфиксное индексирование только ими. Это применимо только к dict=crc и является необязательным; по умолчанию все поля индексируются в инфиксном режиме. Эта настройка похожа на prefix_fields, но вместо этого позволяет ограничить инфиксное индексирование определенными полями.
- CONFIG
table products {
infix_fields = title, name
min_infix_len = 3
dict = crcmax_substring_len = length
Директива max_substring_len устанавливает максимальную длину подстроки, которая будет индексироваться для префиксного или инфиксного поиска. Эта настройка необязательна, и её значение по умолчанию равно 0 (что означает, что индексируются все возможные подстроки). Она применяется только к dict.
По умолчанию индексирование подстрок в dict индексирует все возможные подстроки как отдельные ключевые слова, что может привести к чрезмерно большому полнотекстовому индексу. Поэтому директива max_substring_len позволяет пропускать слишком длинные подстроки, которые, вероятно, никогда не будут искаться.
Например, тестовая таблица из 10 000 записей блога занимает разный объем дискового пространства в зависимости от настроек:
- 6.4 МБ базовый (без подстрок)
- 24.3 МБ (в 3.8 раза больше) с min_prefix_len = 3
- 22.2 МБ (в 3.5 раза больше) с min_prefix_len = 3, max_substring_len = 8
- 19.3 МБ (в 3.0 раза больше) с min_prefix_len = 3, max_substring_len = 6
- 94.3 МБ (в 14.7 раза больше) с min_infix_len = 3
- 84.6 МБ (в 13.2 раза больше) с min_infix_len = 3, max_substring_len = 8
- 70.7 МБ (в 11.0 раза больше) с min_infix_len = 3, max_substring_len = 6
Таким образом, ограничение максимальной длины подстроки может сэкономить 10-15% размера таблицы.
При использовании режима dict=keywords нет влияния на производительность, связанного с длиной подстроки. Поэтому эта директива неприменима и намеренно запрещена в этом случае. Однако, если требуется, вы все равно можете ограничить длину подстроки, которую ищете, в коде приложения.
- CONFIG
table products {
max_substring_len = 12
min_infix_len = 3
dict = crcexpand_keywords = {0|1|exact|star}
Эта настройка расширяет ключевые слова их точными формами и/или звездочками, когда это возможно. Поддерживаемые значения:
- 1 - расширять как до точной формы, так и до формы со звездочками. Например,
runningстанет(running | *running* | =running) exact- дополнять ключевое слово только его точной формой. Например,runningстанет(running | =running)star- дополнять ключевое слово, добавляя*вокруг него. Например,runningстанет(running | *running*)Эта настройка необязательна, и значение по умолчанию равно 0 (ключевые слова не расширяются).
Запросы к таблицам с включенной функцией expand_keywords внутренне расширяются следующим образом: если таблица была построена с включенным префиксным или инфиксным индексированием, каждое ключевое слово внутренне заменяется на дизъюнкцию самого ключевого слова и соответствующего префикса или инфикса (ключевое слово со звездочками). Если таблица была построена с включенными стеммингом и index_exact_words, также добавляется точная форма.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) expand_keywords = '1'POST /cli -d "
CREATE TABLE products(title text, price float) expand_keywords = '1'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'expand_keywords' => '1'
]);utilsApi.sql('CREATE TABLE products(title text, price float) expand_keywords = \'1\'')await utilsApi.sql('CREATE TABLE products(title text, price float) expand_keywords = \'1\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) expand_keywords = \'1\'');utilsApi.sql("CREATE TABLE products(title text, price float) expand_keywords = '1'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) expand_keywords = '1'", true);utils_api.sql("CREATE TABLE products(title text, price float) expand_keywords = '1'", Some(true)).await;table products {
expand_keywords = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}Расширенные запросы, естественно, выполняются дольше, но могут улучшить качество поиска, поскольку документы с точными совпадениями форм должны ранжироваться, как правило, выше, чем документы со стеммированными или инфиксными совпадениями.
Обратите внимание, что существующий синтаксис запросов не позволяет эмулировать этот тип расширения, поскольку внутреннее расширение работает на уровне ключевых слов и расширяет ключевые слова даже внутри операторов фразы или кворума (что невозможно через синтаксис запросов). Взгляните на примеры и на то, как expand_keywords влияет на веса результатов поиска и как "runsy" находится по "runs" без необходимости добавлять звездочку:
- expand_keywords_enabled
- expand_keywords_disabled
mysql> create table t(f text) min_infix_len='2' expand_keywords='1' morphology='stem_en';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> insert into t values(1,'running'),(2,'runs'),(3,'runsy');
Query OK, 3 rows affected (0.00 sec)
mysql> select *, weight() from t where match('runs');
+------+---------+----------+
| id | f | weight() |
+------+---------+----------+
| 2 | runs | 1560 |
| 1 | running | 1500 |
| 3 | runsy | 1500 |
+------+---------+----------+
3 rows in set (0.01 sec)
mysql> drop table t;
Query OK, 0 rows affected (0.01 sec)
mysql> create table t(f text) min_infix_len='2' expand_keywords='exact' morphology='stem_en';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> insert into t values(1,'running'),(2,'runs'),(3,'runsy');
Query OK, 3 rows affected (0.00 sec)
mysql> select *, weight() from t where match('running');
+------+---------+----------+
| id | f | weight() |
+------+---------+----------+
| 1 | running | 1590 |
| 2 | runs | 1500 |
+------+---------+----------+
2 rows in set (0.00 sec)mysql> create table t(f text) min_infix_len='2' morphology='stem_en';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> insert into t values(1,'running'),(2,'runs'),(3,'runsy');
Query OK, 3 rows affected (0.00 sec)
mysql> select *, weight() from t where match('runs');
+------+---------+----------+
| id | f | weight() |
+------+---------+----------+
| 1 | running | 1500 |
| 2 | runs | 1500 |
+------+---------+----------+
2 rows in set (0.00 sec)
mysql> drop table t;
Query OK, 0 rows affected (0.01 sec)
mysql> create table t(f text) min_infix_len='2' morphology='stem_en';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> insert into t values(1,'running'),(2,'runs'),(3,'runsy');
Query OK, 3 rows affected (0.00 sec)
mysql> select *, weight() from t where match('running');
+------+---------+----------+
| id | f | weight() |
+------+---------+----------+
| 1 | running | 1500 |
| 2 | runs | 1500 |
+------+---------+----------+
2 rows in set (0.00 sec)Эта директива никак не влияет на indexer, она влияет только на searchd.
expansion_limit = number
Максимальное количество расширенных ключевых слов для одного шаблона с подстановочными знаками. Подробнее см. здесь.
Стоп-слова — это слова, которые игнорируются при индексации и поиске, обычно из-за их высокой частоты и низкой ценности для результатов поиска.
Manticore Search по умолчанию применяет стемминг к стоп-словам, что может привести к нежелательным результатам, но это можно отключить с помощью опции stopwords_unstemmed.
Небольшие файлы стоп-слов хранятся в заголовке таблицы, и существует ограничение на размер файлов, которые могут быть встроены, как определено опцией embedded_limit.
Стоп-слова не индексируются, но они влияют на позиции ключевых слов. Например, если "the" является стоп-словом, и документ 1 содержит фразу "in office", а документ 2 содержит фразу "in the office", поиск точной фразы "in office" вернет только первый документ, даже несмотря на то, что "the" пропускается как стоп-слово во втором документе. Это поведение можно изменить с помощью директивы stopword_step.
stopwords=path/to/stopwords/file[ path/to/another/file ...]
Настройка stopwords является необязательной и по умолчанию пустой. Она позволяет указать путь к одному или нескольким файлам стоп-слов, разделенным пробелами. Все файлы будут загружены. В режиме реального времени разрешены только абсолютные пути.
Формат файла стоп-слов — это простой текстовый файл в кодировке UTF-8. Данные файла будут токенизированы с учетом настроек charset_table, поэтому вы можете использовать те же разделители, что и в индексируемых данных.
Когда активна индексация ngram_len, стоп-слова, состоящие из символов, подпадающих под ngram_chars, сами токенизируются в N-граммы. Таким образом, каждая отдельная N-грамма становится отдельным стоп-словом. Например, при ngram_len=1 и подходящих ngram_chars стоп-слово test будет интерпретировано как t, e, s, t — четыре различных стоп-слова.
Файлы стоп-слов можно создавать вручную или полуавтоматически. Индексатор предоставляет режим, который создает частотный словарь таблицы, отсортированный по частоте ключевых слов. Верхние ключевые слова из этого словаря обычно можно использовать как стоп-слова. Подробнее см. переключатели --buildstops и --buildfreqs. Верхние ключевые слова из этого словаря обычно можно использовать как стоп-слова.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) stopwords = '/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt'POST /cli -d "
CREATE TABLE products(title text, price float) stopwords = '/usr/local/manticore/data/stopwords.txt stopwords-ru.txt stopwords-en.txt'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'stopwords' => '/usr/local/manticore/data/stopwords.txt stopwords-ru.txt stopwords-en.txt'
]);utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt\'')await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt\'');utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = '/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) stopwords = '/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt'", true);utils_api.sql("CREATE TABLE products(title text, price float) stopwords = '/usr/local/manticore/data/stopwords.txt /usr/local/manticore/data/stopwords-ru.txt /usr/local/manticore/data/stopwords-en.txt'", Some(true)).await;table products {
stopwords = /usr/local/manticore/data/stopwords.txt
stopwords = stopwords-ru.txt stopwords-en.txt
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}В качестве альтернативы вы можете использовать один из стандартных файлов стоп-слов, поставляемых с Manticore. В настоящее время доступны стоп-слова для 50 языков. Вот полный список их псевдонимов:
- af - Африкаанс
- ar - Арабский
- bg - Болгарский
- bn - Бенгальский
- ca - Каталанский
- ckb- Курдский
- cz - Чешский
- da - Датский
- de - Немецкий
- el - Греческий
- en - Английский
- eo - Эсперанто
- es - Испанский
- et - Эстонский
- eu - Баскский
- fa - Персидский
- fi - Финский
- fr - Французский
- ga - Ирландский
- gl - Галисийский
- hi - Хинди
- he - Иврит
- hr - Хорватский
- hu - Венгерский
- hy - Армянский
- id - Индонезийский
- it - Итальянский
- ja - Японский
- ko - Корейский
- la - Латинский
- lt - Литовский
- lv - Латышский
- mr - Маратхи
- nl - Нидерландский
- no - Норвежский
- pl - Польский
- pt - Португальский
- ro - Румынский
- ru - Русский
- sk - Словацкий
- sl - Словенский
- so - Сомали
- st - Сесото
- sv - Шведский
- sw - Суахили
- th - Тайский
- tr - Турецкий
- yo - Йоруба
- zh - Китайский
- zu - Зулу
Например, чтобы использовать стоп-слова для итальянского языка, просто добавьте следующую строку в файл конфигурации:
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) stopwords = 'it'POST /cli -d "
CREATE TABLE products(title text, price float) stopwords = 'it'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'stopwords' => 'it'
]);utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'it\'')await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'it\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'it\'');utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = 'it'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) stopwords = 'it'", true);utils_api.sql("CREATE TABLE products(title text, price float) stopwords = 'it'", Some(true)).await;table products {
stopwords = it
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}Если вам нужно использовать стоп-слова для нескольких языков, вы должны перечислить все их псевдонимы, разделенные запятыми (режим RT) или пробелами (обычный режим):
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) stopwords = 'en, it, ru'POST /cli -d "
CREATE TABLE products(title text, price float) stopwords = 'en, it, ru'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'stopwords' => 'en, it, ru'
]);utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en, it, ru\'')await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en, it, ru\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en, it, ru\'');utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = 'en, it, ru'", true);utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = 'en, it, ru'", true);utils_api.sql("CREATE TABLE products(title text, price float) stopwords = 'en, it, ru'", Some(true)).await;table products {
stopwords = en it ru
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}stopwords_list = 'value1; value2; ...'
Параметр stopwords_list позволяет указать стоп-слова непосредственно в операторе CREATE TABLE. Он поддерживается только в режиме RT.
Значения должны быть разделены точкой с запятой (;). Если необходимо использовать точку с запятой как обычный символ, её нужно экранировать обратной косой чертой (\;).
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
CREATE TABLE products(title text, price float) stopwords_list = 'a; the'POST /cli -d "
CREATE TABLE products(title text, price float) stopwords_list = 'a; the'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'stopwords_list' => 'a; the'
]);utilsApi.sql('CREATE TABLE products(title text, price float) stopwords_list = \'a; the\'')await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords_list = \'a; the\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords_list = \'a; the\'');utilsApi.sql("CREATE TABLE products(title text, price float) stopwords_list = 'a; the'", true);utilsApi.sql("CREATE TABLE products(title text, price float) stopwords_list = 'a; the'", true);utils_api.sql("CREATE TABLE products(title text, price float) stopwords_list = 'a; the'", Some(true)).await;stopword_step={0|1}
Параметр position_increment для стоп-слов является необязательным, допустимые значения — 0 и 1, по умолчанию используется 1.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) stopwords = 'en' stopword_step = '1'POST /cli -d "
CREATE TABLE products(title text, price float) stopwords = 'en' stopword_step = '1'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'stopwords' => 'en, it, ru',
'stopword_step' => '1'
]);utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en\' stopword_step = \'1\'')await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en\' stopword_step = \'1\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en\' stopword_step = \'1\'');utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = \'en\' stopword_step = \'1\'", true);utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = \'en\' stopword_step = \'1\'", true);utils_api.sql("CREATE TABLE products(title text, price float) stopwords = \'en\' stopword_step = \'1\'", Some(true)).await;table products {
stopwords = en
stopword_step = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}stopwords_unstemmed={0|1}
Определяет, применять ли стоп-слова до или после стемминга. Необязательный параметр, по умолчанию 0 (применять фильтр стоп-слов после стемминга).
По умолчанию стоп-слова сами подвергаются стеммингу, а затем применяются к токенам после стемминга (или любой другой морфологической обработки). Это означает, что токен пропускается, когда stem(токен) равен stem(стоп-слово). Такое поведение по умолчанию может привести к неожиданным результатам, когда токен ошибочно сводится к стоп-корню. Например, "Andes" может быть приведено к "and", поэтому, когда "and" является стоп-словом, "Andes" также пропускается.
Однако вы можете изменить это поведение, включив директиву stopwords_unstemmed. При её включении стоп-слова применяются до стемминга (и, следовательно, к исходным формам слов), и токены пропускаются, когда токен равен стоп-слову.
- SQL
- JSON
- PHP
- Python
- Python-asyncio
- javascript
- Java
- C#
- Rust
- CONFIG
CREATE TABLE products(title text, price float) stopwords = 'en' stopwords_unstemmed = '1'POST /cli -d "
CREATE TABLE products(title text, price float) stopwords = 'en' stopwords_unstemmed = '1'"$index = new \Manticoresearch\Index($client);
$index->setName('products');
$index->create([
'title'=>['type'=>'text'],
'price'=>['type'=>'float']
],[
'stopwords' => 'en, it, ru',
'stopwords_unstemmed' => '1'
]);utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en\' stopwords_unstemmed = \'1\'')await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en\' stopwords_unstemmed = \'1\'')res = await utilsApi.sql('CREATE TABLE products(title text, price float) stopwords = \'en\' stopwords_unstemmed = \'1\'');utilsApi.sql("CREATE TABLE products(title text, price float) stopwords = \'en\' stopwords_unstemmed = \'1\'", true);utilsApi.Sql("CREATE TABLE products(title text, price float) stopwords = \'en\' stopwords_unstemmed = \'1\'", true);utils_api.sql("CREATE TABLE products(title text, price float) stopwords = \'en\' stopwords_unstemmed = \'1\'", Some(true)).await;table products {
stopwords = en
stopwords_unstemmed = 1
type = rt
path = tbl
rt_field = title
rt_attr_uint = price
}