mysql ngram_MySQL ngram全文解析器
本教程將向您展示如何使用MySQL ngram全文解析器來支持中文,日文,韓文等表意語言的全文搜索。
MySQL ngram全文解析器簡介
MySQL內置的全文解析器使用空格確定單詞的開始和結束。當涉及漢語,日語或韓語等表意語言語言時,這是一個限制,因為這些語言不使用分詞符。
為了解決這個問題,MySQL提供了ngram全文解析器。自MySQL5.7.6版起,MySQL將ngram全文解析器作為內置的服務器插件,這意味著當MySQL數據庫服務器啟動時,MySQL會自動加載該插件。 MySQL支持用于InnoDB和MyISAM存儲引擎的ngram全文解析器。
根據定義,ngram是來自文本序列的多個字符的連續序列。 ngram全文解析器的主要功能是將文本序列標記為n個字符的連續序列。
以下說明了ngram全文解析器如何標記不同值n的文本序列:
n = 1: 'm','y','s','q','l'
n = 2: 'my', 'ys', 'sq','ql'
n = 3: 'mys', 'ysq', 'sql'
n = 4: 'mysq', 'ysql'
n = 5: 'mysql'
使用 ngram 解析器創建FULLTEXT索引
要創建使用ngram全文解析器的FULLTEXT索引,可以在CREATE TABLE,ALTER TABLE或CREATE INDEX語句中添加WITH PARSER ngram。
例如,以下語句創建新的帖子表,并將標題和正文列添加到使用ngram全文解析器的FULLTEXT索引。
USE testdb;
CREATE TABLE posts (
id INT PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255),
body TEXT,
FULLTEXT ( title , body ) WITH PARSER NGRAM
) ENGINE=INNODB CHARACTER SET UTF8;
以下INSERT語句賂posts表中插入一個新行:
SET NAMES utf8;
INSERT INTO posts(title,body)
VALUES('MySQL全文搜索','MySQL提供了具有許多好的功能的內置全文搜索'),
('MySQL教程','學習MySQL快速,簡單和有趣');
請注意,SET NAMES語句設置客戶端和服務器將用于發送和接收數據的字符集; 在本示例中,它使用的是utf8。
要查看ngram如何標記文本,請使用以下語句:
SET GLOBAL innodb_ft_aux_table="testdb/posts";
SELECT
*
FROM
information_schema.innodb_ft_index_cache
ORDER BY doc_id , position;
執行上面查詢語句,得到以下結果 -
mysql> SELECT
*
FROM
information_schema.innodb_ft_index_cache
ORDER BY doc_id , position;
+------+--------------+-------------+-----------+--------+----------+
| WORD | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+------+--------------+-------------+-----------+--------+----------+
| my | 2 | 3 | 2 | 2 | 0 |
| ys | 2 | 3 | 2 | 2 | 1 |
| sq | 2 | 3 | 2 | 2 | 2 |
| ql | 2 | 3 | 2 | 2 | 3 |
| l全 | 2 | 2 | 1 | 2 | 4 |
| 全文 | 2 | 2 | 1 | 2 | 5 |
| 文搜 | 2 | 2 | 1 | 2 | 8 |
| 搜索 | 2 | 2 | 1 | 2 | 11 |
| ql | 2 | 3 | 2 | 2 | 18 |
| my | 2 | 3 | 2 | 2 | 18 |
| ys | 2 | 3 | 2 | 2 | 18 |
| sq | 2 | 3 | 2 | 2 | 18 |
| l提 | 2 | 2 | 1 | 2 | 22 |
| 提供 | 2 | 2 | 1 | 2 | 23 |
| 供了 | 2 | 2 | 1 | 2 | 26 |
| 了具 | 2 | 2 | 1 | 2 | 29 |
| 具有 | 2 | 2 | 1 | 2 | 32 |
| 有許 | 2 | 2 | 1 | 2 | 35 |
| 許多 | 2 | 2 | 1 | 2 | 38 |
| 多好 | 2 | 2 | 1 | 2 | 41 |
| 好的 | 2 | 2 | 1 | 2 | 44 |
| 的功 | 2 | 2 | 1 | 2 | 47 |
| 功能 | 2 | 2 | 1 | 2 | 50 |
| 能的 | 2 | 2 | 1 | 2 | 53 |
| 的內 | 2 | 2 | 1 | 2 | 56 |
| 內置 | 2 | 2 | 1 | 2 | 59 |
| 搜索 | 2 | 2 | 1 | 2 | 60 |
| 文搜 | 2 | 2 | 1 | 2 | 60 |
| 全文 | 2 | 2 | 1 | 2 | 60 |
| 置全 | 2 | 2 | 1 | 2 | 62 |
| my | 2 | 3 | 2 | 3 | 0 |
| ys | 2 | 3 | 2 | 3 | 1 |
| sq | 2 | 3 | 2 | 3 | 2 |
| ql | 2 | 3 | 2 | 3 | 3 |
| l教 | 3 | 3 | 1 | 3 | 4 |
| 教程 | 3 | 3 | 1 | 3 | 5 |
| 學習 | 3 | 3 | 1 | 3 | 12 |
| 習m | 3 | 3 | 1 | 3 | 15 |
| sq | 2 | 3 | 2 | 3 | 18 |
| ql | 2 | 3 | 2 | 3 | 18 |
| my | 2 | 3 | 2 | 3 | 18 |
| ys | 2 | 3 | 2 | 3 | 18 |
| l快 | 3 | 3 | 1 | 3 | 22 |
| 快速 | 3 | 3 | 1 | 3 | 23 |
| 速, | 3 | 3 | 1 | 3 | 26 |
| ,簡 | 3 | 3 | 1 | 3 | 29 |
| 簡單 | 3 | 3 | 1 | 3 | 32 |
| 單和 | 3 | 3 | 1 | 3 | 35 |
| 和有 | 3 | 3 | 1 | 3 | 38 |
| 有趣 | 3 | 3 | 1 | 3 | 41 |
+------+--------------+-------------+-----------+--------+----------+
50 rows in set
此查詢對于故障排除目的很有用。例如,如果一個單詞不包括在搜索結果中,則該單詞可能沒有被編入索引,因為它是一個停止詞或者可能是其它原因。
設置ngram令牌大小
在前面的示例可以看到,默認情況下,ngram中的令牌大小(n)為2,要更改令牌大小,請使用ngram_token_size配置選項,值的范圍是:1到10。
請注意,較小的令牌大小可使較小的全文搜索索引更快地進行搜索。
因為ngram_token_size是只讀變量,因此您只能使用兩個選項設置其值:
第一種方式,在啟動字符串中:
mysqld --ngram_token_size=1
第二種方式 - 在配置文件中:
[mysqld]
ngram_token_size=1
ngram解析器短語搜索
MySQL將短語搜索轉換成ngram短語搜索。 例如,abc被轉換為ab bc,它返回包含ab bc和abc的文檔。
以下示例顯示在posts表中搜索短語:搜索:
SELECT
id, title, body
FROM
posts
WHERE
MATCH (title , body) AGAINST ('搜索' );
執行上面查詢語句,得到以下結果 -
mysql> SELECT
id, title, body
FROM
posts
WHERE
MATCH (title , body) AGAINST ('搜索' );
+----+---------------+-------------------------------------------+
| id | title | body |
+----+---------------+-------------------------------------------+
| 1 | MySQL全文搜索 | MySQL提供了具有許多好的功能的內置全文搜索 |
+----+---------------+-------------------------------------------+
1 row in set
用ngram處理搜索結果
自然語言模式
在自然語言模式搜索中,搜索項被轉換為ngram值的并集。 假設令牌大小為2或者二進制,則搜索項mysql被轉換為我的my ys sq和ql。
SELECT
*
FROM
posts
WHERE
MATCH (title , body) AGAINST ('簡單和有趣' IN natural language MODE);
執行上面查詢語句,得到以下結果 -
mysql> SELECT
*
FROM
posts
WHERE
MATCH (title , body) AGAINST ('簡單和有趣' IN natural language MODE);
+----+-----------+---------------------------+
| id | title | body |
+----+-----------+---------------------------+
| 2 | MySQL教程 | 學習MySQL快速,簡單和有趣 |
+----+-----------+---------------------------+
1 row in set
布爾模式
在BOOLEAN MODE搜索中,搜索項被轉換成ngram短語搜索。 例如:
SELECT
*
FROM
posts
WHERE
MATCH (title , body) AGAINST ('簡單和有趣' IN BOOLEAN MODE);
執行上面查詢語句,得到以下結果 -
mysql> SELECT
*
FROM
posts
WHERE
MATCH (title , body) AGAINST ('簡單和有趣' IN BOOLEAN MODE);
+----+-----------+---------------------------+
| id | title | body |
+----+-----------+---------------------------+
| 2 | MySQL教程 | 學習MySQL快速,簡單和有趣 |
+----+-----------+---------------------------+
1 row in set
ngram通配符搜索
ngram FULLTEXT索引僅包含ngram,因此它不知道短語的開始。執行通配符搜索時,可能會返回意外的結果。
以下規則將應用于使用ngram FULLTEXT搜索索引的通配符搜索:
如果通配符中的前綴短語短于ngram令牌大小,則查詢返回所有包含以前綴項為起始的ngram令牌的文檔。 例如:
SELECT
id, title, body
FROM
posts
WHERE
MATCH (title , body) AGAINST ('my*' );
執行上面查詢語句,得到以下結果 -
mysql> SELECT
id, title, body
FROM
posts
WHERE
MATCH (title , body) AGAINST ('my*' );
+----+---------------+-------------------------------------------+
| id | title | body |
+----+---------------+-------------------------------------------+
| 1 | MySQL全文搜索 | MySQL提供了具有許多好的功能的內置全文搜索 |
| 2 | MySQL教程 | 學習MySQL快速,簡單和有趣 |
+----+---------------+-------------------------------------------+
2 rows in set
如果通配符中的前綴短語長于ngram令牌大小,則MySQL將將前綴術語轉換為ngram短語,并忽略通配符運算符。 請參閱以下示例:
SELECT
id, title, body
FROM
posts
WHERE
MATCH (title , body) AGAINST ('mysqld*' );
執行上面查詢語句,得到以下結果 -
mysql> SELECT
id, title, body
FROM
posts
WHERE
MATCH (title , body) AGAINST ('mysqld*' );
+----+---------------+-------------------------------------------+
| id | title | body |
+----+---------------+-------------------------------------------+
| 1 | MySQL全文搜索 | MySQL提供了具有許多好的功能的內置全文搜索 |
| 2 | MySQL教程 | 學習MySQL快速,簡單和有趣 |
+----+---------------+-------------------------------------------+
2 rows in set
在這個例子中,短語“mysqld”被轉換為ngram短語:my ys sq ql ld,因此返回包含其中一個短語的所有文檔。
處理停止詞
ngram解析器不包括在停止詞列表中包含停止詞的令牌。例如,假設ngram_token_size為2,文檔包含abc。 ngram解析器將文檔標記為ab和bc。 如果b是一個停用詞,則ngram將包含ab和bc,因為它們包含b。
請注意,如果語言不是英語,則必須定義自己的詞條列表。 此外,長度大于ngram_token_size的停止詞將被忽略。
在本教程中,您已經學會了如何使用MySQL ngram全文解析器來處理表意語言的全文搜索。
¥ 我要打賞
糾錯/補充
收藏
加QQ群啦,易百教程官方技術學習群
注意:建議每個人選自己的技術方向加群,同一個QQ最多限加 3 個群。
總結
以上是生活随笔為你收集整理的mysql ngram_MySQL ngram全文解析器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode 142. 环形链表 I
- 下一篇: LeetCode 312. 戳气球(DP