Главная / Прочие материалы > Полнотекстовый поиск MySQL

Полнотекстовый поиск MySQL

Отличие обычного поиска от полнотекстового в том что, при первом искать сущности сайта, будь то товары магазина или статьи блога, можно по конкретному параметру, например по дате добавления. Полнотекстовый поиск, в свою очередь, подразумевает поиск по совпадающим ключевым словам запроса и текста искомого товара или статьи.

Самым наглядным примером полнотекстового поиска являются поисковые системы, такие как yandex.ru или google.ru, при вводе запроса В«Полнотекстовый поиск MySQLВ» в поисковую строку система разобьет фразу на три слова:


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

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


Как сделать полнотекстовый поиск MySQL


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

Реализовать поиск по таблицам MySQL можно разными способами:
  1. Оператор LIKE
  2. Оператор REGEXP
  3. Операторы AGAINST и MATCH

Первые два оператора самый примитивный вариант для поиска по сайту, и кроме того очень медлительный и требующий большой производительности сервера.

Поиск по сайту с помощью оператора LIKE


Например, реализовать поиск по таблице статей, используя оператор LIKE, можно следующим запросом:
	SELECT * FROM `aticle` WHERE `content` LIKE “%новость%”

Данный запрос выдаст все записи, т.е. все статьи в тексте которых встретится слово "новость", если в содержании самой статьи нет данного слова, но оно в присутствует в заголовке, статья не будет найдена.

Чтобы искать статьи также и по совпадению в заголовках, можно усовершенствовать запрос:

SELECT * 
 FROM  `aticle` 
 WHERE `content` LIKE “%новость%” 
    OR `title` LIKE “%новость%”

Этот SQL запрос учитывает два текстовых поля, по которым произойдет поиск статьи, но использует уже несколько операторов LIKE, а это двойная нагрузка на сервер. Кроме того если пользователь запросит статьи по фразе "новость дня", то получи те статьи, которые содержат исключительно именно такую фразу: "новость дня".

MySql match – все что нужно для поиска по сайту


В арсенале программиста, использующего mysql, имеется стандартный инструмент для полнотекстового поиска MySql – операторы: MATCH и AGAINST.

Возьмем, к примеру, задачу поиска товаров по базе интернет магазина. Как правило, товар имеет ряд текстовых характеристик, таких как: название, описание, артикул, ключевые слова и др.

Используя для реализации полнотекстового поиска MATCH и AGAINST запрос может выглядит так:

SELECT * 
 FROM `product` WHERE MATCH(`meta_desc`, `meta_keywords`) AGAINST('Full')

При этом, для работоспособности запроса должен существовать индекс таблицы товаров с типом FULLTEXT, объединяющий в себе перечень полей для поиска:

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

WHERE MATCH(`meta_keywords`) – такой запрос выдаст ошибку и чтобы ее избежать нужно создать отдельный индекс и включить в него только одно поле (`meta_keywords`).

Для поиска части строки, а не строгого соответствия , нужно использовать модификатор INBOOLEANMODE и символ ‘*‘:

SELECT * 
 FROM `product` 
 WHERE 
   MATCH(`meta_desc`, `meta_keywords`) 
   AGAINST('*ful*' IN BOOLEAN MODE)

Данный запрос аналогичен результату при использовании LIKE ="%ful%", только использует значительно меньше ресурсов благодаря системе индексов MySQL

Искать не точное соответствие по введенной фразе и соответствие по ее частям можно таким образом:

SELECT * 
 FROM `product` 
 WHERE 
   MATCH(`meta_desc`, `meta_keywords`) 
   AGAINST('*ful**nam*' IN BOOLEAN MODE)


При таком запросе в результат попадут записи имеющие вхождения фрагментов слов ful и nam

Надо учесть, что при работе с MATCH запрещено использовать в качестве именно полей зарезервированные слова.

Существует список запрещенных к использованию слов, то есть следующими словами нельзя называть поля таблиц, чтобы потом использовать их в полнотекстовом поиске MySql:


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

Как я и обещал, в начале статьи, задача реализации полнотекстового поиска в MySQL сводится к минимуму действий:
  1. Создание индекса для полей занятых в поиске.
  2. Выполнение sql запроса.



Оригинал статьи по ссылке
18-03-2016, 18:44. Разместил: administrator
Вернуться назад