Как Mysql реализует полнотекстовый поиск, ключевые слова

MySQL

Введение

Сегодня коллега спросил меня, как я могу использовать Mysql для реализации функции полнотекстового поиска, аналогичной ElasticSearch, и запускать точки для поисковых ключевых слов? У меня сразу возник вопрос? Почему бы просто не использовать es? Простой и удобный в использовании и быстрый. Но я слышал, как он сказал, что объем данных невелик, время, данное заказчиком, очень ограничено, а времени на сборку нет, так что давайте посмотрим на функцию полнотекстового поиска Mysql! MySQL Начиная с версии 5.7.6, MySQL имеет встроенный полнотекстовый синтаксический анализатор ngram для поддержки сегментации слов на китайском, японском и корейском языках. До MySQL 5.7.6 полнотекстовое индексирование поддерживает только полнотекстовое индексирование на английском языке, а не полнотекстовое индексирование на китайском языке.Необходимо использовать токенизатор для предварительной обработки китайских абзацев в слова, а затем сохранять их в базе данных. При тестировании этой статьи использовался движок базы данных InnoDB Mysql 5.7.6.

Анализ исходного текста

mysql全文检索

Во-вторых, полнотекстовый анализатор ngram

Ngram — это последовательность n последовательных слов в фрагменте текста. Полнотекстовый синтаксический анализатор ngram способен размечать текст, где каждое слово представляет собой последовательность из последовательных n слов. Например, токенизация «hello world» с помощью полнотекстового синтаксического анализатора ngram:

n=1: '你', '好', '世', '界' 
n=2: '你好', '好世', '世界' 
n=3: '你好世', '好世界' 
n=4: '你好世界'

Глобальная переменная ngram_token_size используется в MySQL для настройки размера n в ngram, диапазон ее значений — от 1 до 10, а значение по умолчанию — 2. Обычно ngram_token_size устанавливается на минимальное количество слов для запроса. Если вам нужно найти одно слово, установите для ngram_token_size значение 1. При значении по умолчанию 2 поиск слова не дает результатов. Поскольку китайские слова состоят как минимум из двух китайских иероглифов, рекомендуется использовать значение по умолчанию, равное 2.

Давайте посмотрим на размер ngram_token_size по умолчанию для Mysql:

show variables like 'ngram_token_size'

mysql全文检索

Есть два способа установить переменную ngram_token_size:

1. Указать при запуске команды mysqld

mysqld --ngram_token_size=2

2. Измените файл конфигурации mysql.

[mysqld] 
ngram_token_size=2

3. Полнотекстовый индекс

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

mysql全文检索

1. Создайте полнотекстовый индекс при создании таблицы

CREATE TABLE `t_wenshu` (
  `province` varchar(255) DEFAULT NULL,
  `caseclass` varchar(255) DEFAULT NULL,
  `casenumber` varchar(255) DEFAULT NULL,
  `caseid` varchar(255) DEFAULT NULL,
  `types` varchar(255) DEFAULT NULL,
  `title` varchar(255) DEFAULT NULL,
  `content` longtext,
  `updatetime` varchar(255) DEFAULT NULL,
  FULLTEXT KEY `content` (`content`) WITH PARSER `ngram`
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2. Методом изменения таблицы

ALTER TABLE t_wenshu ADD FULLTEXT INDEX content_index (content) WITH PARSER ngram;

3. Через метод создания индекса

CREATE FULLTEXT INDEX content_index ON t_wenshu (content) WITH PARSER ngram;

4. Режим поиска

поиск на естественном языке

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

Логический поиск

(В БУЛЕВОМ РЕЖИМЕ) Исключите слова, которые имеют более половины совпадающих строк. Например, если в каждой строке есть слово this, при использовании этого для проверки вы не найдете никаких результатов. Это очень полезно, когда количество количество записей очень велико. Причина в том, что база данных считает бессмысленным поиск всех строк. В настоящее время это почти расценивается как стоп-слово (слово прерывания); Булев режим поиска может использовать операторы, которые могут поддерживать указанное ключевое слово должны появляться или не должны появляться или сложные запросы, такие как высокий или низкий вес ключевых слов.

   ● IN BOOLEAN MODE的特色: 
      ·不剔除50%以上符合的row。 
      ·不自动以相关性反向排序。 
      ·可以对没有FULLTEXT index的字段进行搜寻,但会非常慢。 
      ·限制最长与最短的字符串。 
      ·套用Stopwords。

   ● 搜索语法规则:
     +   一定要有(不含有该关键词的数据条均被忽略)。 
     -   不可以有(排除指定关键词,含有该关键词的均被忽略)。 
     >   提高该条匹配数据的权重值。 
     <   降低该条匹配数据的权重值。
     ~   将其相关性由正转负,表示拥有该字会降低相关性(但不像-将之排除),只是排在较后面权重值降低。 
     *   万用字,不像其他语法放在前面,这个要接在字符串后面。 
     " " 用双引号将一段句子包起来表示要完全相符,不可拆字。

Получение расширения запроса

Примечание: (С РАСШИРЕНИЕМ ЗАПРОСА) Используйте с осторожностью, так как расширение запроса может привести к множеству некоррелированных запросов!

5. Поисковый запрос

1) Запросите записи, содержащие «кража» в содержании, оператор запроса выглядит следующим образом

select caseid,content, MATCH ( content) AGAINST ('盗窃罪') as score from t_wenshu where MATCH ( content) AGAINST ('盗窃罪' IN NATURAL LANGUAGE MODE)

mysql全文检索

2) Запросите записи, содержащие в содержании «ссоры и провоцирование неприятностей», формулировка запроса выглядит следующим образом.

select caseid,content, MATCH ( content) AGAINST ('寻衅滋事') as score from t_wenshu where MATCH ( content) AGAINST ('寻衅滋事' IN NATURAL LANGUAGE MODE) ;

mysql全文检索

3) Для одного китайского символа запросите запись, содержащую «I» в содержимом, оператор запроса выглядит следующим образом.

select caseid,content, MATCH ( content) AGAINST ('我') as score from t_wenshu where MATCH ( content) AGAINST ('我' IN NATURAL LANGUAGE MODE) ;

mysql全文检索

Примечание. Поскольку значение установленной глобальной переменной ngram_token_size равно 2. Если вы хотите запросить один китайский иероглиф, вам нужно изменить ngram_token_size = 1 в файле конфигурации my.ini и перезапустить службу mysqld, я не буду пробовать это здесь.

4) Предложения, содержащие «опасное вождение» и «ссориться и провоцировать неприятности» в содержимом поля запроса, следующие:

select caseid,content, MATCH (content) AGAINST ('+危险驾驶 +寻衅滋事') as score from t_wenshu where MATCH (content) AGAINST ('+危险驾驶 +寻衅滋事' IN BOOLEAN MODE);

mysql全文检索

5) Содержимое поля запроса содержит «опасное вождение», но не содержит «завязывание ссор и провоцирование неприятностей» следующим образом:

select caseid,content, MATCH (content) AGAINST ('+危险驾驶 -寻衅滋事') as score from t_wenshu where MATCH (content) AGAINST ('+危险驾驶 -寻衅滋事' IN BOOLEAN MODE);

mysql全文检索

6) Утверждение, содержащее «опасное вождение» или «ссоры и провоцирование неприятностей» в поле запроса, выглядит следующим образом:

select caseid,content, MATCH (content) AGAINST ('危险驾驶 寻衅滋事') as score from t_wenshu where MATCH (content) AGAINST ('危险驾驶 寻衅滋事' IN BOOLEAN MODE);

mysql全文检索

6. Резюме

1) Прежде чем использовать полнотекстовый индекс Mysql, узнайте о поддержке каждой версии;

2) Полнотекстовая индексация в N раз быстрее, чем +%, но могут быть проблемы с точностью;

3) Если для полнотекстового индексирования требуется большой объем данных, рекомендуется сначала добавить данные, а затем уже создавать индекс;

4) Для китайцев можно использовать версии после MySQL 5.7.6 или сторонние плагины, такие как Sphinx и Lucene;

5) Имя поля, используемое функцией ПОИСКПОЗ(), должно совпадать с именем поля, указанным при создании полнотекстового индекса, и может быть полем только одной и той же таблицы и не может пересекать таблицы;

over

mysql全文检索