Лучший способ справиться с ошибками в полнотекстовом поиске MySQL

У меня около 2000 строк в базе данных mysql.

Каждая строка имеет максимум 300 символов и содержит предложение или два.

Я использую mysql, встроенный в полнотекстовый поиск, для поиска этих строк.

Я хотел бы добавить функцию, чтобы опечатки и случайные неверные ошибки были исправлены, если это возможно.

Например, если кто-то вводит "правый шладдер" в поле поиска, это будет приравниваться к "правому плечу" при выполнении поиска.

Каковы ваши предложения по простейшему способу добавления такого рода функций? Стоит ли добавлять внешнюю поисковую систему, вроде lucene? (Похоже, что для такого небольшого набора данных это слишком много.) Или есть более простой способ?

Спасибо (заблаговременно) за вашу помощь.

Ответы

Ответ 1

Я думаю, вы должны использовать SOUNDS LIKE или SOUNDEX()

Поскольку ваш набор данных настолько мал, одним из решений может быть создание новой таблицы для хранения отдельных слов или значений soundex, содержащихся в каждом текстовом поле, и использование SOUNDS LIKE в этой таблице.

например:

SELECT * FROM table where id IN 
(
    SELECT refid FROM tableofwords 
    WHERE column SOUNDS LIKE 'right' OR column SOUNDS LIKE 'shlder'
)

см. ниже: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html

Я верю, что не может дикая карта проложить строку:(

Ответ 2

Технический термин для того, что вы ищете, расстояние Левенштейна, которое используется для вычисления разницы между двумя последовательностями (в этом случае a последовательность символов, которая является строкой).

На самом деле PHP имеет две встроенные функции, первая из которых Similar_text, а другая называется levenshtein, который должен помочь вам решить вашу проблему. Вам нужно будет проверить, достаточно ли он для ваших нужд.

Ответ 3

MySQL не поддерживает поиск SOUNDEX в полном объеме.

Если вы хотите реализовать lucene-подобную структуру, это означает, что вам нужно взять все документы, разделить их на слова и затем построить индекс для каждого слова.

Когда кто-то ищет "правильный шелдер", вы должны сделать SOUNDEX для каждого слова в таблице миров:

    $search = 'right shlder';
preg_match_all('(\w+)', $search, $matches);
if (!empty($matches[0]))
   $sounds = array_map('soundex', $matches[0]);
$query = 'SELECT word FROM words_list
    WHERE SOUNDEX(word) IN(\''.join('\',\'',$sounds).'\')';

а затем выполните полнотекстовый поиск:

$query2 = 'SELECT * FROM table
    WHERE MATCH(fultextcolumn)
    AGAINST ('.join (' OR ', $resuls).' IN BINARY MODE)';

Где $result - массив с результатами первого запроса.