Я пытаюсь создать небольшой поиск для моего сайта. Я попытался использовать полнотекстовый поиск по индексу, но я никогда не смог заставить его работать. Вот что я придумал:
if(isset($_GET['search'])) { $search = str_replace('-', ' ', $_GET['search']); $result = array(); $titles = mysql_query("SELECT title FROM Entries WHERE title LIKE '%$search%'"); while($row = mysql_fetch_assoc($titles)) { $result[] = $row['title']; } $tags = mysql_query("SELECT title FROM Entries WHERE tags LIKE '%$search%'"); while($row = mysql_fetch_assoc($tags)) { $result[] = $row['title']; } $text = mysql_query("SELECT title FROM Entries WHERE entry LIKE '%$search%'"); while($row = mysql_fetch_assoc($text)) { $result[] = $row['title']; } $result = array_unique($result); }
Таким образом, в основном, он просматривает все заголовки, текстовые теги и теги всех записей в БД. Это работает прилично, но мне просто интересно, насколько это эффективно? Это будет только для небольшого блога. В любом случае мне просто интересно, можно ли это сделать более эффективно.
LIKE '%pattern%'
сделать запросы LIKE '%pattern%'
эффективными. Как только вы получите нетривиальное количество данных, использование этих подстановочных запросов выполняется в сотни или тысячи раз медленнее, чем использование полнотекстового индексационного решения.
Вы должны посмотреть презентацию, которую я сделал для Университета MySQL: http://www.slideshare.net/billkarwin/practical-full-text-search-with-my-sql
Вот как заставить его работать:
Сначала убедитесь, что в вашей таблице используется механизм хранения MyISAM. Индексы MySQL FULLTEXT поддерживают только таблицы MyISAM. ( edit 11/1/2012: MySQL 5.6 вводит индексный тип FULLTEXT для таблиц InnoDB.)
ALTER TABLE Entries ENGINE=MyISAM;
Создайте полный текст.
CREATE FULLTEXT INDEX searchindex ON Entries(title, tags, entry);
Найдите его!
$search = mysql_real_escape_string($search); $titles = mysql_query("SELECT title FROM Entries WHERE MATCH(title, tags, entry) AGAINST('$search')"); while($row = mysql_fetch_assoc($titles)) { $result[] = $row['title']; }
Обратите внимание, что столбцы, которые вы MATCH
предложении MATCH
, должны быть одинаковыми столбцами в том же порядке, что и те, которые вы указали в определении полнотекстового индекса. Иначе это не сработает.
Я пытался использовать полнотекстовый поиск по индексу, но я никогда не смог заставить его работать … Мне просто интересно, можно ли сделать это более эффективным.
Это точно так же, как сказать: «Я не мог понять, как использовать эту бензопилу, поэтому я решил срубить это дерево красного дерева с помощью карманного ножа. Как я могу сделать эту работу, а также бензопилу?»
Что касается вашего комментария о поиске слов, которые соответствуют более 50% строк.
В руководстве MySQL сказано следующее :
Пользователи, которым необходимо обходить ограничение 50%, могут использовать режим логического поиска; см. Раздел 11.8.2, «Логические полнотекстовые поиски» .
И это :
50% -ый порог для поиска естественного языка определяется конкретной выбранной схемой взвешивания. Чтобы отключить его, найдите следующую строку в хранилище / myisam / ftdefs.h:
#define GWS_IN_USE GWS_PROB
Измените эту строку следующим образом:
#define GWS_IN_USE GWS_FREQ
Затем перекомпилируйте MySQL. В этом случае нет необходимости перестраивать индексы.
Кроме того, вы можете искать временные слова . Это слова, которые игнорируются полнотекстовым поиском, потому что они слишком распространены. Такие слова, как «the» и т. Д. См. http://dev.mysql.com/doc/refman/5.1/en/fulltext-stopwords.html.
Использование LIKE
является полным текстом.
Вам нужно использовать ... WHERE MATCH(column) AGAINST('the query')
, чтобы получить доступ к полнотекстовому поиску.
MySQL Полнотекстовый поиск работает – я бы посмотрел на него и отлаживал его, а не пытался это сделать. Выполнение 3 отдельных запросов MySQL не будет таким эффективным.
Если вы хотите попытаться сделать так эффективно, вы можете разделить операторы LIKE
в одном запросе с OR
между ними.