Исправление орфографии, также известное как:
и так далее, это функциональность программного обеспечения, которая предлагает альтернативы или автоматически исправляет введённый вами текст. Концепция исправления набранного текста восходит к 1960-м годам, когда учёный-компьютерщик Уоррен Тейтельман, который также изобрёл команду "отменить", представил философию вычислений под названием D.W.I.M., или "Делай Что Я Имею в Виду". Вместо того чтобы программировать компьютеры на приём только идеально отформатированных инструкций, Тейтельман утверждал, что их следует программировать на распознавание очевидных ошибок.
Первым известным продуктом, предоставившим функциональность исправления орфографии, был Microsoft Word 6.0, выпущенный в 1993 году.
Есть несколько способов реализации исправления орфографии, но важно отметить, что не существует чисто программного способа с достойным качеством преобразовать вашу опечатку "ipone" в "iphone". В основном, необходима система, основанная на наборе данных. Набор данных может быть:
Manticore предоставляет опцию нечёткого поиска и команды CALL QSUGGEST и CALL SUGGEST, которые могут быть использованы для целей автоматического исправления орфографии.
Функция нечёткого поиска позволяет осуществлять более гибкое сопоставление, учитывая небольшие вариации или опечатки в поисковом запросе. Она работает аналогично обычному оператору SQL SELECT или JSON-запросу /search, но предоставляет дополнительные параметры для управления поведением нечёткого сопоставления.
ПРИМЕЧАНИЕ: Опция
fuzzyтребует наличия Manticore Buddy. Если она не работает, убедитесь, что Buddy установлен.ПРИМЕЧАНИЕ: Опция
fuzzyнедоступна для многозапросов.
SELECT
...
MATCH('...')
...
OPTION fuzzy={0|1}
[, distance=N]
[, preserve={0|1}]
[, layouts='{be,bg,br,ch,de,dk,es,fr,uk,gr,it,no,pt,ru,se,ua,us}']
}
Примечание: При проведении нечёткого поиска через SQL, в выражении MATCH не должно быть никаких полнотекстовых операторов, кроме оператора поиска по фразе, и оно должно содержать только слова, которые вы намерены сопоставить.
SELECT * FROM mytable WHERE MATCH('someting') OPTION fuzzy=1, layouts='us,ua', distance=2;
Пример более сложного запроса нечёткого поиска с дополнительными фильтрами:
SELECT * FROM mytable WHERE MATCH('someting') OPTION fuzzy=1 AND (category='books' AND price < 20);
POST /search
{
"table": "test",
"query": {
"bool": {
"must": [
{
"match": {
"*": "ghbdtn"
}
}
]
}
},
"options": {
"fuzzy": true,
"layouts": ["us", "ru"],
"distance": 2
}
}
+------+-------------+
| id | content |
+------+-------------+
| 1 | something |
| 2 | some thing |
+------+-------------+
2 rows in set (0.00 sec)
SELECT * FROM mytable WHERE MATCH('hello wrld') OPTION fuzzy=1, preserve=1;
POST /search
{
"table": "test",
"query": {
"bool": {
"must": [
{
"match": {
"*": "hello wrld"
}
}
]
}
},
"options": {
"fuzzy": true,
"preserve": 1
}
}
+------+-------------+
| id | content |
+------+-------------+
| 1 | hello wrld |
| 2 | hello world |
+------+-------------+
2 rows in set (0.00 sec)
POST /search
{
"table": "table_name",
"query": {
<full-text query>
},
"options": {
"fuzzy": {true|false}
[,"layouts": ["be","bg","br","ch","de","dk","es","fr","uk","gr","it","no","pt","ru","se","ua","us"]]
[,"distance": N]
[,"preserve": {0|1}]
}
}
Примечание: Если вы используете query_string, имейте в виду, что он не поддерживает полнотекстовые операторы, кроме оператора поиска по фразе. Строка запроса должна состоять исключительно из слов, которые вы хотите сопоставить.
fuzzy: Включает или выключает нечёткий поиск.distance: Устанавливает расстояние Левенштейна для сопоставления. По умолчанию 2.preserve: 0 или 1 (по умолчанию: 0). При установке в 1 сохраняет слова, не имеющие нечётких совпадений, в результатах поиска (например, "hello wrld" возвращает и "hello wrld", и "hello world"). При установке в 0 возвращает только слова с успешными нечёткими совпадениями (например, "hello wrld" возвращает только "hello world"). Особенно полезно для сохранения коротких слов или имён собственных, которых может не быть в Manticore Search.layouts: Раскладки клавиатуры для обнаружения ошибок ввода, вызванных несоответствием раскладки клавиатуры (например, ввод "ghbdtn" вместо "привет" при использовании неправильной раскладки). Manticore сравнивает позиции символов в разных раскладках, чтобы предложить исправления. Требуется как минимум 2 раскладки для эффективного обнаружения несоответствий. По умолчанию раскладки не используются. Используйте пустую строку '' (SQL) или массив [] (JSON), чтобы отключить это. Поддерживаемые раскладки включают:
be - Бельгийская раскладка AZERTYbg - Стандартная болгарская раскладкаbr - Бразильская раскладка QWERTYch - Швейцарская раскладка QWERTZde - Немецкая раскладка QWERTZdk - Датская раскладка QWERTYes - Испанская раскладка QWERTYfr - Французская раскладка AZERTYuk - Британская раскладка QWERTYgr - Греческая раскладка QWERTYit - Итальянская раскладка QWERTYno - Норвежская раскладка QWERTYpt - Португальская раскладка QWERTYru - Русская раскладка JCUKENse - Шведская раскладка QWERTYua - Украинская раскладка JCUKENus - Американская раскладка QWERTY
{.scale-0.7}Обе команды доступны через SQL и поддерживают запросы к локальным (plain и real-time) и распределённым таблицам. Синтаксис следующий:
CALL QSUGGEST(<word or words>, <table name> [,options])
CALL SUGGEST(<word or words>, <table name> [,options])
options: N as option_name[, M as another_option, ...]
Эти команды предоставляют все предложения из словаря для заданного слова. Они работают только с таблицами, у которых включено инфиксирование и используется dict=keywords. Они возвращают предлагаемые ключевые слова, расстояние Левенштейна между предложенным и исходным ключевым словом, а также статистику документов по предложенному ключевому слову.
Если первый параметр содержит несколько слов, то:
CALL QSUGGEST вернёт предложения только для последнего слова, игнорируя остальные.CALL SUGGEST вернёт предложения только для первого слова.Это единственное различие между ними. Поддерживается несколько опций для настройки:
| Опция | Описание | По умолчанию |
| - | - | - |
| limit | Возвращает N лучших совпадений | 5 |
| max_edits | Оставляет только слова из словаря с расстоянием Левенштейна меньше или равным N | 4 |
| result_stats | Предоставляет расстояние Левенштейна и количество документов для найденных слов | 1 (включено) |
| delta_len | Оставляет только слова из словаря с разницей в длине меньше N | 3 |
| max_matches | Количество совпадений для сохранения | 25 |
| reject | Отклонённые слова — это совпадения, которые не лучше уже находящихся в очереди совпадений. Они помещаются в очередь отклонённых, которая сбрасывается, если слово всё же может попасть в очередь совпадений. Этот параметр определяет размер очереди отклонённых (как reject*max(max_matched,limit)). Если очередь отклонённых заполнена, движок прекращает поиск потенциальных совпадений | 4 |
| result_line | альтернативный режим отображения данных, возвращающий все предложения, расстояния и количество документов каждое в отдельной строке | 0 |
| non_char | не пропускать слова из словаря с неалфавитными символами | 0 (пропускать такие слова) |
| sentence | Возвращает исходное предложение с заменой последнего слова на подобранное. | 0 (не возвращать полное предложение) |
| force_bigrams | Принудительно использовать биграммы (n-граммы из 2 символов) вместо триграмм для всех длин слов, что может улучшить сопоставление для слов с ошибками транспозиции | 0 (использовать триграммы для слов ≥6 символов) |
| search_mode | Уточняет предложения, выполняя поиск по индексу. Принимает 'phrase' для точного соответствия фразы или 'words' для соответствия по модели "мешок слов". При включении добавляет столбец found_docs, показывающий количество документов, и пересортировывает результаты по убыванию found_docs, затем по возрастанию distance. | N/A (отключено по умолчанию) |
Чтобы показать, как это работает, создадим таблицу и добавим в неё несколько документов.
create table products(title text) min_infix_len='2';
insert into products values (0,'Crossbody Bag with Tassel'), (0,'microfiber sheet set'), (0,'Pet Hair Remover Glove');
Как видно, слово с опечаткой "crossbUdy" исправляется на "crossbody". По умолчанию CALL SUGGEST/QSUGGEST возвращают:
distance — расстояние Левенштейна, означающее, сколько правок потребовалось, чтобы преобразовать заданное слово в предложенноеdocs — количество документов, содержащих предложенное словоЧтобы отключить отображение этой статистики, можно использовать опцию 0 as result_stats.
call suggest('crossbudy', 'products');
+-----------+----------+------+
| suggest | distance | docs |
+-----------+----------+------+
| crossbody | 1 | 1 |
+-----------+----------+------+
Если первый параметр — не одно слово, а несколько, то CALL SUGGEST вернёт предложения только для первого слова.
call suggest('bagg with tasel', 'products');
+---------+----------+------+
| suggest | distance | docs |
+---------+----------+------+
| bag | 1 | 1 |
+---------+----------+------+
Если первый параметр — не одно слово, а несколько, то CALL SUGGEST вернёт предложения только для последнего слова.
CALL QSUGGEST('bagg with tasel', 'products');
+---------+----------+------+
| suggest | distance | docs |
+---------+----------+------+
| tassel | 1 | 1 |
+---------+----------+------+
Добавление 1 as sentence заставляет CALL QSUGGEST возвращать всё предложение с исправленным последним словом.
CALL QSUGGEST('bag with tasel', 'products', 1 as sentence);
+-------------------+----------+------+
| suggest | distance | docs |
+-------------------+----------+------+
| bag with tassel | 1 | 1 |
+-------------------+----------+------+
Опция 1 as result_line меняет способ отображения предложений в выводе. Вместо показа каждого предложения в отдельной строке, она отображает все предложения, расстояния и количество документов в одной строке. Вот пример, демонстрирующий это:
CALL QSUGGEST('bagg with tasel', 'products', 1 as result_line);
+----------+--------+
| name | value |
+----------+--------+
| suggests | tassel |
| distance | 1 |
| docs | 1 |
+----------+--------+
Опция force_bigrams может помочь со словами, содержащими ошибки транспозиции, например, "ipohne" и "iphone". Используя биграммы вместо триграмм, алгоритм может лучше обрабатывать перестановки символов.
CALL SUGGEST('ipohne', 'products', 1 as force_bigrams);
+--------+----------+------+
| suggest| distance | docs |
+--------+----------+------+
| iphone | 2 | 1 |
+--------+----------+------+
Опция search_mode улучшает предложения, выполняя фактические поисковые запросы по индексу для подсчёта количества документов, содержащих каждую предложенную фразу или комбинацию слов. Это помогает ранжировать предложения на основе реальной релевантности документов, а не только статистики словаря.
Опция принимает два значения:
'phrase' - Выполняет поиск точных фраз. Например, при предложении "bag with tassel" выполняется поиск точной фразы "bag with tassel" и подсчитываются документы, содержащие эти слова как смежную фразу.'words' - Выполняет поиск по модели "мешок слов". Например, при предложении "bag with tassel" выполняется поиск bag with tassel (без кавычек) и подсчитываются документы, содержащие все эти слова, независимо от порядка или наличия других слов между ними.ПРИМЕЧАНИЕ: Опция
search_modeработает только тогда, когда включен режимsentence(т.е. когда ввод содержит несколько слов). Для запросов из одного словаsearch_modeигнорируется.ПРИМЕЧАНИЕ: Соображения производительности: Каждый кандидат на предложение запускает отдельный поисковый запрос к индексу. Если вам нужно оценить много кандидатов, рассмотрите использование меньшего значения
limit, чтобы сократить количество выполняемых поисков.
Когда search_mode включен, результаты включают столбец found_docs, показывающий количество документов для каждого предложения, и результаты пересортировываются по убыванию found_docs, а затем по возрастанию distance.
CALL QSUGGEST('bag with tasel', 'products', 1 as sentence, 'phrase' as search_mode);
+-------------------+----------+------+-------------+
| suggest | distance | docs | found_docs |
+-------------------+----------+------+-------------+
| bag with tassel | 1 | 13 | 10 |
| bag with tazer | 2 | 27 | 3 |
+-------------------+----------+------+-------------+
-- With phrase matching: finds exact phrases only
CALL QSUGGEST('test carp', 'products', 1 as sentence, 'phrase' as search_mode);
-- With words matching: finds documents with all words regardless of order
CALL QSUGGEST('test carp', 'products', 1 as sentence, 'words' as search_mode);
-- Phrase mode results:
+----------------+----------+------+-------------+
| suggest | distance | docs | found_docs |
+----------------+----------+------+-------------+
| test car | 1 | 17 | 5 |
| test carpet | 2 | 19 | 4 |
+----------------+----------+------+-------------+
-- Words mode results (more matches for "test carpet" due to word separation):
+----------------+----------+------+-------------+
| suggest | distance | docs | found_docs |
+----------------+----------+------+-------------+
| test carpet | 2 | 19 | 19 |
| test car | 1 | 17 | 5 |
+----------------+----------+------+-------------+
Понимание разницы:
'phrase'): Ищет точные последовательности. Запрос "test carpet" соответствует только документам, где эти слова встречаются вместе в точном порядке (например, "test carpet cleaning" соответствует, а "test the carpet" или "carpet test" - нет).'words'): Ищет наличие всех слов в документе, порядок не имеет значения. Запрос test carpet соответствует любому документу, содержащему оба слова "test" и "carpet" где угодно (например, "test the carpet", "test red carpet", "carpet test" - все соответствуют).CALL SUGGEST в небольшом веб-приложении.