Лучший способ справиться с ошибками в полнотекстовом поиске MySQL - PullRequest
19 голосов
/ 26 августа 2011

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

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

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

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

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

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

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

Ответы [ 3 ]

10 голосов
/ 26 августа 2011

Я думаю, вы должны использовать 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

Я полагаю, что не возможно подстановочный знак поиска строки :(

8 голосов
/ 26 августа 2011

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 - это массив с результатами первого запроса.

8 голосов
/ 26 августа 2011

Технический термин для того, что вы ищете, это Расстояние Левенштейна , которое используется для вычисления разницы между двумя последовательностями (в данном случае последовательность символов, которая является строкой).1004 * PHP фактически имеет две встроенные функции для этого, первая из которых Similar_text , а другая - levenshtein , которая должна помочь вам решить вашу проблему.Вам придется тестировать, если он достаточно быстр для ваших нужд.

...