PHP/MySQL мелкомасштабный нечеткий поиск


Я ищу возможность реализовать нечеткий поиск для небольшого приложения PHP/MySQL. В частности, у меня есть база данных с примерно 2400 записями (записи добавляются со скоростью около 600 в год, так что это небольшая база данных). Три поля, представляющие интерес, - это адрес, фамилия и дата. Я хочу иметь возможность выполнять поиск по одному из этих полей и, по сути, иметь допуск к ошибкам правописания/символов. т. Е. Адрес "123 Main Street" также должен соответствовать "123 Main St", "123 Main St"., "123 Mian St", "123 Man St", "132 Main St" и т. Д., А также для имени и даты.

Основные проблемы, которые у меня возникают с ответами на другие подобные вопросы:

  • Невозможно определить синонимы для каждого возможного неправильного написания, забудьте сделать это для дат и имен.
  • Lucene и т. Д. Кажутся очень тяжеловесными для такого ограниченного набора данных поиска (назовите его максимум 5000 записей, 3 поля на запись).
  • Просто делать что-то с подстановочными знаками не кажется логичным с все возможные орфографические ошибки.

Есть какие-нибудь предложения? Я знаю, что это будет невозможно сделать изначально с MySQL, но поскольку набор данных настолько ограничен, я бы хотел, чтобы он был относительно простым... возможно, класс PHP, который получает все записей из БД, использует какой-то алгоритм сравнения и возвращает идентификаторы похожих записей?

Спасибо, Джейсон

Author: Jason Antman, 2009-12-16

2 answers

Ответ Раззи (или с помощью Дамерау–Левенштейна) ранжирует список совпадений кандидатов в соответствии с их близостью к ключу поиска. (Будьте осторожны: если клавиша "12 Main St", то "13 Main St" имеет то же расстояние ввода, что и "12 Moin St", но вы можете присвоить ей низкий ранг или даже исключить ее, как в случае с 11 и 22 Main St и т. Д.)

Но как вы выбираете список кандидатов приемлемого размера для ранжирования?

Один из способов - вычислить значение метафоны (или значения, используя двойной метафон) для каждого слова в строках, которые вы собираетесь искать. Сохраните каждую из этих метафон в другой таблице с идентификатором строки, содержащей исходную строку. Затем вы можете быстро выполнить поиск по этим значениям метафон, НАПРИМЕР, с помощью "ключ%", где ключ - это метафона слова из текста поиска.

Ознакомьтесь с предлагаемым ответом на в этой теме . Это довольно аккуратно и должно хорошо работать для небольших баз данных.

 7
Author: , 2009-12-17 23:09:56

Если это очень маленькая база данных, вы можете загрузить все данные сразу и использовать алгоритм, подобный Jaro-Winkler для вашего поиска. У них есть реализация на PHP, которую вы можете найти здесь.

Имхо это работает действительно хорошо. Взгляните на пример реализации здесь . Я знаю, что этот поиск использует тот же алгоритм, и он очень хорошо может найти "Nintedno". Он также сортирует результаты для вас, основываясь на том, какой результат лучше всего соответствует вашему запросу.

 3
Author: Razzie, 2009-12-16 13:38:01