Полнотекстовый поиск для MySQL с помощью FULLTEXT индексов

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

MySQL поддерживает FULLTEXT индексы с версии 3.23, это позволяет производить полноценный поиск для столбцов с типами VARCHAR и TEXT с помощью определенного SQL выражения. Для начала нам потребуется создать этот самый FULLTEXT индекс. Пример кода:

ALTER TABLE articles ADD FULLTEXT(title, content);

Таким не сложным выражением мы добавили FULLTEXT индекс для полей title и content таблицы articles. Как видите, FULLTEXT индекс можно добавить для нескольких столбцов сразу. Как же теперь выполнить поиск? Очень просто:

SELECT title, content FROM articles
WHERE MATCH (title, content) AGAINST ('Поиск в MySQL');

Таким не сложным выражением мы выберем из таблицы articles поля title, content всех записей, где MySQL найдет словосочетание «Поиск в MySQL» в столбцах title, content. Поиск выполняется без учета регистра символов. Кроме того, MySQL сортирует результаты в порядке убывания релевантности. Как это происходит и что это значит? MySQL создает значение релевантности в виде числа с плавающей точкой в зависимости от того, насколько точное найдено совпадение, после чего сортирует данные в порядке убывания. При желание, данное число можно получить:

SELECT id, MATCH (title, content)
AGAINST ('Получаем значение релевантности')
FROM articles;

Как видите для поиска используются две функции MATCH и AGAINST.

MATCH — функция служит для определения столбца(ов) по которым будет произведен поиск. Список столбцов в MATCH обязательно должен быть определен внутри индекса FULLTEXT.

AGAINST — функция выполняющая непосредственный поиск.

Вы можете использовать булевый режим, для более тонкого поиска. Например, выполним поиск всех статей, в который встречается слово «булевый», но отсутствует слово «режим»:

SELECT title, content FROM articles 
WHERE MATCH(title, content) 
AGAINST ('+булевый -режим' IN BOOLEAN MODE);

Как это работает? Если вы не указываете символы «+» или «-» то MySQL ищет любое слово из списка в каждой записи (аналогия с оператором OR). Если вы указывается символ «+», MySQL выберет записи в которых данное слово обязательно присутствует, (как оператор AND). Если вы указываете символ «-«, MySQL выберет записи, в который данного слова нет (как оператор NOT).

Более подробное описание можно найти на сайте PHPClub или в официальной документации MySQL.

Как видите, ничего сложного. Задавайте свои ответы. Да, да. Я допускаю много ошибок, но фраза «задавайте свои ответы» просто интернет мем. Уже много пичем получил, как я глупый и пишу такие глупости. Спорить не буду, но в данном случае это не так.

Комментарии 9

  • здравствуйте. а как сделать точный поиск по длинной фразе?

    • Не уверен что понял ваш вопрос. Можете привести пример?

      Кстати, зацените мой английский блог. Ссылка в шапке сайта.

  • Спасибо, очень пригодилось

  • Перерыл весь интернет но не нашел ответа. Как сделать такой запрос на sqlite? Заранее спасибо.

  • хотелось бы узнать как искать полнотекстовым поиском email, так как в булевом режиме на @ мскл как-то странно реагирует

  • было упоминание в статье:

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

    SELECT id, MATCH (title, content)
    AGAINST (‘Получаем значение релевантности’)
    FROM articles;

    на выходе мы получим это число либо id записей?

    • При:

      SELECT id, MATCH (title, content)
      AGAINST (‘Получаем значение релевантности’)
      FROM articles;

      Мы получим id + match number. Хотя, я давно так не делал и могу путать. Поправьте если не прав.

      Кстати, зацените мой английский блог. Ссылка в шапке сайта.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *