С самой первой книжки по пхп, поиск по сайту у меня ассоциировался с конструкцией LIKE в MySQL. На не очень навороченных сайтах и на не очень навороченных поисках - она работала на ура, даже если полей, по которым шел поиск, было много. На маленьких сайтах вообще многое допустимо
Однако, как только надо было сделать что-нить более или менее серьезное на этом фронте - как сразу LIKE шел в топку из-за своих тормозов. И не важно что это было - Sphinx, Lucene или написанный самим заказчиком типа мегаиндексатор (было однажды и такое) - возможности MySQL отметались - и задача поиска переносилась на другие приложения. И только недавно я узнал, что оказывается MySQL сама отлично умеет все это делать!
Оказалось, что еще с версии 3.23.23 в MySQL была предусмотрена такая возможность - для этого нужно было создать Fulltext Index по нужным полям (на примере добавления в уже существующую таблицу):
ALTER TABLE news ADD FULLTEXT(headline, story);
И можно использовать для поиска конструкции вида:
SELECT headline, story FROM news WHERE MATCH (headline,story) AGAINST ('Hurricane');
как по идее ясно из кода - в AGAINST - слово, по которому ищем, в MATCH - поля по которым ищем
Мало того, что такой запрос выберет все что нужно, так записи еще и будут отсортированы по релевантности. Да-да, он и это умеет делать!
Но и это еще не все
Поисковики, как правило, поддерживают свой мини-язык запросов. Тут это тоже есть:
SELECT headline, story FROM news WHERE MATCH (headline,story) AGAINST ('+Hurricane -Katrina' IN BOOLEAN MODE);
выберет все записи со словом "Hurricane", но не со словом "Katrina".
Не буду перепечатывать мануал - полнотекстовый поиск - это просто конфетка. Однако есть и определенные трудности:
- По умолчанию короткие слова игнорируются. Короткие - это меньше 4 символов. Для этой настройки есть специальные переменные, однако если нет возможности их править на сервере заказчика - могут возникнуть проблемы;
- Поиск по пустому значению не выдает все результаты (хотя спорно что такое поведение верное, но обычно именно так) - он же выдает ничего. Поэтому, вероятно для именно этой ситуации придется писать дополнительный запрос;
- Опять же по умолчанию некоторые слова игнорируются (типа предлогов, артиклей и т.п. - к примеру, the, have, some) - настраивается, но если нет доступа - ну вы поняли :);
- Если слово встречается более чем в 50% записей - то оно просто игнорируется. По идее - здраво, однако будет геморно объяснить тестеру почему такое творится, особенно на маленькой тестовой базе;
- Вроде как не работает ток в MyISAM?
- Слова ищутся целиком. Не как LIKE '%text%'.
В целом же - полнотекстовый поиск - клевая штука. Используя его - вовсе не нужно париться над встаиванием дополнительного чужеродного функционала в ваш проект, править чужие баги и мучаться с ручной (или по крону) переиндексацией базы. Да, со своими ньюансами, но в целом - тру. Советую
ALTER TABLE news ADD FULLTEXT(headline, story);
…а вот с этим я что-то не понял: как именно записать в пхп-скрипте-то?
с поиском понятно:
$result = mysql_query(”SELECT * FROM news WHERE MATCH(name) AGAINST(’слово’)”, $db);
…а для ALTER?
$result = mysql_query(”ALTER TABLE имя_таблицы ADD FULLTEXT(список_полей_через_запятую)”, $db); и так для всех таблиц в которых нужно проиндексировать поля
Цитата: “Слова ищутся целиком. Не как LIKE ‘%text%’ ”
Можно искать по началу слова, используя оператором усечения *. Пример (из мануала):
apple* найдет “apple”, “apples”, “applesauce”, “applet” и т.д.
К сожалению, оператор усечения можно использовать лишь в конце слова. Да и подглючивает это всё, лучше всё же сфинкс