Как улучшить поиск в базе данных с помощью полнотекстового поиска в MySQL 5.6 в Ubuntu 16.04

Вступление

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

В частности, FTS извлекает документы, которые не полностью соответствуют критериям поиска. Documents - это объекты базы данных, содержащие текстовые данные. Это означает, что когда пользователь ищет «кошки и собаки», например, приложение, поддерживаемое FTS, может возвращать результаты, которые содержат слова отдельно (только «кошки» или «собаки»), содержат слова в другом порядке. («Собаки и кошки») или содержат варианты слов («кошка» или «собака»). Это дает приложениям преимущество в угадывании значения пользователя и более быстром возвращении более релевантных результатов.

Технически говоря, системы управления базами данных (СУБД), такие как MySQL, обычно допускают частичный поиск текста с использованием предложений + LIKE +. Однако эти запросы, как правило, неэффективны для больших наборов данных. Они также ограничены точным соответствием пользовательского ввода, что означает, что запрос может не дать результатов, даже если есть документы с соответствующей информацией.

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

Предпосылки

Прежде чем начать этот урок, вам понадобится:

Шаг 1 - Создание тестовых данных

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

Сначала зайдите в консоль MySQL. Вам будет предложено ввести пароль * root *, который вы установили при установке MySQL.

mysql -u root -p

Как только вы подключитесь, ваш запрос изменится на + mysql> +.

Затем создайте новую базу данных с именем + testdb +. Эта база данных будет содержать данные испытаний.

CREATE DATABASE testdb;

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

USE testdb;

Затем создайте в базе данных таблицу под названием + news + со столбцами для примеров статей агрегатора новостей.

CREATE TABLE news (
  id INT NOT NULL AUTO_INCREMENT,
  title TEXT NOT NULL,
  content TEXT NOT NULL,
  author TEXT NOT NULL,

  PRIMARY KEY (id)
);

Давайте пройдемся по тому, что делает эта команда:

  • + CREATE TABLE + - это команда SQL, которая создает таблицу, похожую на многие другие базы данных.

  • + news + - это имя таблицы.

  • + title,` + content` и + author - текстовые столбцы с неограниченной длиной.

  • + NOT NULL + - это объявление, используемое для пометки столбцов, которые не могут иметь значения null (хотя они могут содержать пустые строки).

  • + id + - это первичный индекс таблицы со специальным типом + AUTO_INCREMENT +, который автоматически заполняет поле идентификатора следующим доступным идентификатором.

Теперь добавьте несколько примеров данных в таблицу.

INSERT INTO news (id, title, content, author) VALUES
   (1, 'Pacific Northwest high-speed rail line', 'Currently there are only a few options for traveling the 140 miles between Seattle and Vancouver and none of them are ideal.', 'Greg'),
   (2, 'Hitting the beach was voted the best part of life in the region', 'Exploring tracks and trails was second most popular, followed by visiting the shops and then traveling to local parks.', 'Ethan'),
   (3, 'Machine Learning from scratch', 'Bare bones implementations of some of the foundational models and algorithms.', 'Jo');

Давайте пройдемся по тому, что делает эта команда:

  • + INSERT + вставляет данные.

  • + INTO + указывает, куда должны быть вставлены данные. В данном случае это таблица + news +.

  • + (id, title, content, author) VALUES + указывает столбцы, в которых должны храниться значения данных каждой записи.

  • Последние три строки - это три строки данных, которые мы добавляем в таблицу. Каждый содержит пример статьи для новостного веб-сайта с + title +, некоторым + content + и именем + author + '.

Каждая запись также имеет уникальный идентификатор + id +, который автоматически вводится в индекс базы данных. Database index - это структура данных, которая повышает производительность операций поиска данных. Этот индекс хранится отдельно от основных данных. Он обновляет информацию о любых изменениях в содержимом таблицы за счет дополнительных записей и сравнительно небольшого дискового пространства. Его небольшой размер и индивидуальная структура данных позволяют индексам работать намного эффективнее, чем использование основного табличного пространства для выбора запросов.

Теперь, когда у нас есть некоторые данные, мы можем начать писать запросы для поиска этих данных с использованием FTS.

Шаг 2 - Создание индекса FTS и использование функций FTS

Давайте создадим индекс для имеющихся у нас текстовых столбцов, чтобы мы могли использовать FTS.

Для этого мы будем использовать эксклюзивную команду MySQL под названием + FULLTEXT +. Эта команда говорит MySQL поместить все поля, которые мы хотим иметь возможность искать с помощью FTS, во внутренний индекс.

ALTER TABLE news ADD FULLTEXT (title, content, author);

Это работает путем объединения всех текстовых столбцов и их очистки (например, убрав пунктуацию и сделав прописные буквы строчными). Теперь, когда этот индекс создан, он будет обновляться любым запросом SQL, который изменяет содержимое исходной таблицы.

Затем попробуйте выполнить полнотекстовый поиск «Сиэтл Бич» с помощью функции + MATCH () AGAINST () +.

SELECT * FROM news WHERE MATCH (title,content,author) AGAINST ('' IN NATURAL LANGUAGE MODE)\G

Часть + MATCH () + команды указывает, какой набор столбцов индексируется с использованием FTS; он должен соответствовать списку столбцов, который вы использовали для создания индекса. Часть + AGAINST () + указывает, для какого слова мы выполняем полнотекстовый поиск, в данном примере это "Сиэтл Бич".

+ В РЕЖИМЕ ЕСТЕСТВЕННОГО ЯЗЫКА + означает, что искомые слова предоставляются непосредственно из пользовательского ввода без какой-либо предварительной обработки. MySQL предполагает режим естественного языка по умолчанию, поэтому вам не нужно указывать его явно.

+ \ G + в конце запроса выше приводит к тому, что каждый столбец в выводе выводится на новой строке. Это может сделать длинные результаты немного легче для чтения. Вывод вышеуказанной команды будет выглядеть следующим образом:

Output*************************** 1. row ***************************
    id: 1
 title: Pacific Northwest high-speed rail line
content: Currently there are only a few options for traveling the 140 miles between  and Vancouver and none of them are ideal.
author: Greg
*************************** 2. row ***************************
    id: 2
 title: Hitting the  was voted the best part of life in the region
content: Exploring tracks and trails was second most popular, followed by visiting the shops and then traveling to local parks.
author: Ethan
2 rows in set (0.00 sec)

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

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

Шаг 3 - уточнение результатов FTS

Есть два метода, которые могут помочь сделать результаты полнотекстового поиска более актуальными. Один - это фильтрация по значению релевантности результатов, а другой - использование + IN BOOLEAN +, чтобы исключить отдельные слова из результатов и указать максимальное расстояние между поисковыми терминами.

Использование показателя релевантности

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

Получите оценки релевантности для каждой строки на основе запроса «поездки в парки».

SELECT id, MATCH (title,content,author) AGAINST ('') as score FROM news;

Часть этой команды + as score + помечает второй столбец в выводе как + score +. В противном случае он будет помечен командой, используемой для его заполнения, которая в данном случае была + MATCH (название, содержание, автор) ПРОТИВ ('путешествие в парки') +.

Результат будет выглядеть примерно так:

Output+----+----------------------+
| id | score                |
+----+----------------------+
|  1 | 0.031008131802082062 |
|  2 |  0.25865283608436584 |
|  2 |  0                    |
+----+----------------------+
3 rows in set (0.00 sec)

Третья строка имеет оценку релевантности 0, потому что ни один из поисковых запросов не появляется в ней. Первая строка содержит слово «путешествовать», но не «к» или «парки», и имеет очень низкий показатель релевантности «+ 0,03 ». Вторая строка, содержащая все слова, имеет наивысшую оценку релевантности: « 0,25 +».

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

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

  • Он показывает только строки с ненулевыми значениями релевантности, добавляя + WHERE MATCH (заголовок, содержание, автор) ПРОТИВ ('')> 0 +

  • Он сортирует результаты по релевантности, добавляя + ORDER BY score DESC +

SELECT id, MATCH (title,content,author) AGAINST ('') as score FROM news WHERE MATCH (title,content,author) AGAINST ('') > 0 ORDER BY score DESC;

Вам нужно повторить функцию + MATCH () AGAINST () + в предложении + WHERE + из-за ограничений SQL на то, что может быть включено в это предложение.

Вывод будет выглядеть так:

Output+----+----------------------+
| id | score                |
+----+----------------------+
|  2 |  0.25865283608436584 |
|  1 | 0.031008131802082062 |
+----+----------------------+
2 rows in set (0.01 sec)

Наиболее релевантный результат, строка 2, отображается первым, а затем - менее релевантная строка 1. Строка 3 вообще не отображается, потому что ее оценка релевантности равна 0.

Вы можете изменить срезы, чтобы продолжить точную настройку результатов. Например, если вы используете + 0.1 + вместо + 0 + в качестве обрезки, будет возвращена только строка 2.

Использование IN BOOLEAN

На шаге 2 вы использовали режим по умолчанию + IN NATURAL LANGUAGE при указании термина запроса. Есть еще один режим, + IN BOOLEAN +, который позволяет исключать отдельные слова из поиска, определять диапазон того, как далеко слова во входных данных должны быть друг от друга, и многое другое.

Чтобы опустить термин в запросе, используйте оператор минус с + IN BOOLEAN +. Следующая команда вернет результаты, которые содержат слово «путешествия», но не содержат слова «Сиэтл».

SELECT * FROM news WHERE MATCH (title,content,author) AGAINST ()\G

Результаты покажут только строку 2:

Output*************************** 1. row ***************************
    id: 2
 title: Hitting the beach was voted the best part of life in the region
content: Exploring tracks and trails was second most popular, followed by visiting the shops and then traveling to local parks.
author: Ethan
1 row in set (0.01 sec)

Это работает, потому что оператор минус говорит DMS пометить любой документ исключенными словами с оценкой релевантности 0. В этом режиме отображаются только результаты с ненулевым показателем релевантности.

Вы также можете использовать + IN BOOLEAN MODE +, чтобы указать максимальное расстояние между поисковыми терминами. Это расстояние измеряется словами и, что важно, включает в себя условия поиска. Например, фраза «кошки и собаки» имеет расстояние 3.

Следующая команда возвращает результаты, в которых слова «путешествия» и «мили» отображаются не более чем с двумя словами между ними.

SELECT * FROM news WHERE MATCH (title,content,author) AGAINST ()\G

Вы увидите один результат, который соответствует + пройдя 140 миль в строке '+ content' в строке 2.

Output*************************** 1. row ***************************
    id: 1
 title: Pacific Northwest high-speed rail line
content: Currently there are only a few options for traveling the 140 miles between Seattle and Vancouver and none of them are ideal.
author: Greg
1 row in set (0.00 sec)

Если вы измените + @ 4 + на + @ 3 + в исходной команде, вы не увидите результатов.

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

Заключение

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

Если вы хотите дополнительно изучить возможности MySQL FTS, вы можете прочитать официальную документацию по полнотекстовому поиску MySQL 5.6.

Related