Я работаю в компании, которая осуществляет поиск по организациям города, совеобразные «Желтые страницы». В ходе работы пришло задание: «Станислав, нам нужна проверка орфографии при поиске!». Ну что же делать? К сожалению прямого доступа к серверу не имею, поэтому пришлось использовать связку PHP+postgreSQL+TSearch2, не рассчитывая на aspell, pspell и т.д. Тем более за стабильную, правильную работу TSearch2 я уверен. настройка tsearch2
В ходе работы нашел данную функцию, в качестве демонстрации выполнил запрос: SELECT * from ts_debug('slovar', 'test'); И увидел довольно интересный результат! В котором сразу же обратил внимание на заголовки полей.
И тут ко мне пришла мысль. А что если в данный запрос подставить всю поисковую фразу? Например:
SELECT * from ts_debug('slovar','Где прадаются плюшки?');
Приглядевшись я обнаружил, что правильно настроенный TEXT MAPPING творит чудеса. Все дело в том, что в настройках словаря установлен приоритет языковых пакетов. И следовательно в случае, если слово не прошло по приоритетным словарям, то оно остается как есть и следовательно в ts_debug поле dictionary будет равно simple.
В конце концов приходим к следующему запросу:
И как не трудно заметить, то token как раз будет содержать слово с ошибкой.
Текущая версия проверки орфографии дошла до момента, в котором человеку приводятся варианты для замены ошибочного слова. Идет учет таких ошибок как:
Более того в случае того, если имеем несколько вариантов исправления ошибок, то выводим то слово, которое наиболее часто встречается в базе. (Данный рейтинг слов находится в отдельной таблице) Плюс изначальный рейтинг был сформирован с помощью толкового словаря Даля :)
Все эти функции напрямую связанны с запросом указанным выше. Ведь скажем чтобы узнать какие из вариантов опечаток- верны, достаточно исправить условие запроса на обратное.
ts_debug или поиск ошибок
В ходе работы нашел данную функцию, в качестве демонстрации выполнил запрос: SELECT * from ts_debug('slovar', 'test'); И увидел довольно интересный результат! В котором сразу же обратил внимание на заголовки полей.
=====================================================================
| alias | description | token | dictionaries | dictionary | lexemes |
И тут ко мне пришла мысль. А что если в данный запрос подставить всю поисковую фразу? Например:
SELECT * from ts_debug('slovar','Где прадаются плюшки?');
Приглядевшись я обнаружил, что правильно настроенный TEXT MAPPING творит чудеса. Все дело в том, что в настройках словаря установлен приоритет языковых пакетов. И следовательно в случае, если слово не прошло по приоритетным словарям, то оно остается как есть и следовательно в ts_debug поле dictionary будет равно simple.
В конце концов приходим к следующему запросу:
SELECT * FROM
(
SELECT dict.token, regdictionaryout(dict.dictionary)||'' as sdict
FROM ts_debug('mydict_ru','Великая фраза пользователя с осибками и без ошибок') dict
) dict
WHERE sdict='simple';
И как не трудно заметить, то token как раз будет содержать слово с ошибкой.
Куда дальше?
Текущая версия проверки орфографии дошла до момента, в котором человеку приводятся варианты для замены ошибочного слова. Идет учет таких ошибок как:
- Лишний символ
- Перестановка символов
- Не правильная раскладка клавиатуры
- Подстановка пропущенных символов
- Замена символов(с учетом рядом стоящих символов на клавиатуре и «созвучных» звуков)
- Залипание клавиши
- Подстановка пробела в случае, если человек ввёл два слова слитно
Более того в случае того, если имеем несколько вариантов исправления ошибок, то выводим то слово, которое наиболее часто встречается в базе. (Данный рейтинг слов находится в отдельной таблице) Плюс изначальный рейтинг был сформирован с помощью толкового словаря Даля :)
Все эти функции напрямую связанны с запросом указанным выше. Ведь скажем чтобы узнать какие из вариантов опечаток- верны, достаточно исправить условие запроса на обратное.