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

Во-вторых, полнотекстовый анализатор 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'

Есть два способа установить переменную ngram_token_size:
1. Указать при запуске команды mysqld
mysqld --ngram_token_size=2
2. Измените файл конфигурации mysql.
[mysqld]
ngram_token_size=2
3. Полнотекстовый индекс
Возьмите определенные данные документа в качестве примера, создайте новую таблицу данных t_wenshu, создайте полнотекстовый индекс для поля содержимого документа и импортируйте 10w фрагментов тестовых данных.

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)

2) Запросите записи, содержащие в содержании «ссоры и провоцирование неприятностей», формулировка запроса выглядит следующим образом.
select caseid,content, MATCH ( content) AGAINST ('寻衅滋事') as score from t_wenshu where MATCH ( content) AGAINST ('寻衅滋事' IN NATURAL LANGUAGE MODE) ;

3) Для одного китайского символа запросите запись, содержащую «I» в содержимом, оператор запроса выглядит следующим образом.
select caseid,content, MATCH ( content) AGAINST ('我') as score from t_wenshu where MATCH ( content) AGAINST ('我' IN NATURAL LANGUAGE MODE) ;

Примечание. Поскольку значение установленной глобальной переменной 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);

5) Содержимое поля запроса содержит «опасное вождение», но не содержит «завязывание ссор и провоцирование неприятностей» следующим образом:
select caseid,content, MATCH (content) AGAINST ('+危险驾驶 -寻衅滋事') as score from t_wenshu where MATCH (content) AGAINST ('+危险驾驶 -寻衅滋事' IN BOOLEAN MODE);

6) Утверждение, содержащее «опасное вождение» или «ссоры и провоцирование неприятностей» в поле запроса, выглядит следующим образом:
select caseid,content, MATCH (content) AGAINST ('危险驾驶 寻衅滋事') as score from t_wenshu where MATCH (content) AGAINST ('危险驾驶 寻衅滋事' IN BOOLEAN MODE);

6. Резюме
1) Прежде чем использовать полнотекстовый индекс Mysql, узнайте о поддержке каждой версии;
2) Полнотекстовая индексация в N раз быстрее, чем +%, но могут быть проблемы с точностью;
3) Если для полнотекстового индексирования требуется большой объем данных, рекомендуется сначала добавить данные, а затем уже создавать индекс;
4) Для китайцев можно использовать версии после MySQL 5.7.6 или сторонние плагины, такие как Sphinx и Lucene;
5) Имя поля, используемое функцией ПОИСКПОЗ(), должно совпадать с именем поля, указанным при создании полнотекстового индекса, и может быть полем только одной и той же таблицы и не может пересекать таблицы;
over