mysql with parser_InnoDB全文索引:N-gram Parser【转】

InnoDB默认的全文索引parser非常合适于Latin,因为Latin是通过空格来分词的。但对于像中文,日文和韩文来说,没有这样的分隔符。一个词可以由多个字来组成,所以我们需要用不同的方式来处理。在MySQL 5.7.6中我们能使用一个新的全文索引插件来处理它们:n-gramparser.

什么是N-gram?

在全文索引中,n-gram就是一段文字里面连续的n个字的序列。例如,用n-gram来对”信息系统”来进行分词,得到的结果如下:

N-gram 例子

1

2

3

4

N=1:'信','息','系','统';

N=2:'信息','息系','系统';

N=3:'信息系','息系统';

N=4:'信息系统';

如何在InnoDB中使用N-gram Parser?

N-gram parser是默认加载到MySQL中并可以直接使用的。我们只需要在DDL中创建全文索引时使用WITH PARSER ngram。比如,下面的SQL语句在MySQL 5.7.6及更高版本上可以运行。

N-gram DDL示例

1

2

3

4

5

6

7

8

9

mysql>CREATE TABLE articles

(

FTS_DOC_ID BIGINT UNSIGNEDAUTO_INCREMENT NOTNULLPRIMARY KEY,

title VARCHAR(100),

FULLTEXT INDEX ngram_idx(title)WITH PARSER ngram

)Engine=InnoDB CHARACTER SET utf8mb4;

Query OK,0rows affected(0.06sec)

mysql># ALTER TABLE articles ADD FULLTEXT INDEX ngram_idx(title) WITH PARSER ngram;

mysql># CREATE FULLTEXT INDEX ngram_idx ON articles(title) WITH PARSER ngram;

我们引入了一个新的全局变量叫ngram_token_size。由它来决定n-gram中n的大小,也就是词的大小。它的默认值是2,这个时候,我们使用的是bigram。它的合法的取值范围是1到10。现在,我们很自然会想到一个问题:实际应用中应该如何设置ngram_token_size值的大小呢?当然,我们推荐使用2。但是你也可以通过如下这个简单的规则来可以选择任何合法的值:设置到你希望能查询到的最小的词的大小。如果你想查询到单个字,那么我们需要设置为1。 ngram_token_size的值设置的越小,全文索引占用的空间也越小。一般来说,查询正好等于ngram_token_size的词,速度会更快,但是查询比它更长的词或短语,则会变慢。

N-gram分词处理

N-gram parser和系统默认的全文索引parser有如下不同点:

无用词(stopword)处理:通常,对于一个新的词,我们会查找stopwords表,看是否有匹配的词。如果有,这个词就不会加入到全文索引中。但是在n-gram中,我们会查找stopwords表,看是否包含里面的词。这样处理的原因是,在中日韩的文本中,有很多没有意义的字符,词语和标点符号。比如,如果我们把‘的’加入到stopwords表中,那么对于句子‘信息的系统’,在默认情况下我们分词结果为‘信息’,‘系统’。其中‘息的’和‘的系’被过滤掉了。

我们可以通过查询INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE和INFORMATION_SCHEMA.INNODB_FT_TABLE_TABLE来查询哪些词在全文索引里面。这是一个非常有用的调试工具。如果我们发现一个包含某个词的文档,没有如我们所期望的那样出现在查询结果中,那么这个词可能是因为某些原因不在全文索引里面。比如,它含有stopword,或者它的大小小于ngram_token_size等等。这个时候我们就可以通过查询这两个表来确认。下面是一个简单的例子:

简单的调试示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

mysql>INSERT INTO articles(title)VALUES('信息系统');

Query OK,1row affected(0.01sec)

mysql>SET GLOBALinnodb_ft_aux_table="test/articles";

Query OK,0rows affected(0.00sec)

mysql>SELECT *FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;

+--------+--------------+-------------+-----------+--------+----------+

|WORD|FIRST_DOC_ID|LAST_DOC_ID|DOC_COUNT|DOC_ID|POSITION|

+--------+--------------+-------------+-----------+--------+----------+

|信息|1|1|1|1|0|

|息系|1|1|1|1|3|

|系统|1|1|1|1|6|

+--------+--------------+-------------+-----------+--------+----------+

3rows inset(0.00sec)

N-gram查询处理

文本查询(Text Searches)

在自然语言模式(NATURAL LANGUAGE MODE)下,文本的查询被转换为n-gram分词查询的并集。例如,(‘信息系统’)转换为(‘信息 息系 系统’)。下面一个例子:

自然语言模式示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

mysql>INSERT INTO articles(title)VALUES('信息系统'),('信息 系统'),('信息的系统'),('信息'),('系统'),('息系');

Query OK,6rows affected(0.01sec)

Records:6Duplicates:0Warnings:0

mysql>SELECT *FROM articles WHERE MATCH(title)AGAINST('信息系统'INNATURAL LANGUAGE MODE);

+------------+-----------------+

|FTS_DOC_ID|title|

+------------+-----------------+

|1|信息系统|

|6|息系|

|2|信息系统|

|3|信息的系统|

|4|信息|

|5|系统|

+------------+-----------------+

6rows inset(0.01sec)

在布尔模式(BOOLEAN MODE),文本查询被转化为n-gram分词的短语查询。例如,(‘信息系统’)转换为(“‘信息 息系 系统'”)。

布尔模式示例

1

2

3

4

5

6

7

mysql>SELECT *FROM articles WHERE MATCH(title)AGAINST('信息系统'INBOOLEANMODE);

+------------+--------------+

|FTS_DOC_ID|title|

+------------+--------------+

|1|信息系统|

+------------+--------------+

1row inset(0.00sec)

通配符查询(Wildcard Searches)

如果前缀的长度比ngram_token_size小,那么查询结果将返回在全文索引中所有以这个词作为前缀的n-gram的词。

通配符查询示例-1

1

2

3

4

5

6

7

8

9

10

mysql>SELECT *FROM articles WHERE MATCH(title)AGAINST('信*'INBOOLEANMODE);

+------------+-----------------+

|FTS_DOC_ID|title|

+------------+-----------------+

|1|信息系统|

|2|信息系统|

|3|信息的系统|

|4|信息|

+------------+-----------------+

4rows inset(0.00sec)

如果前缀的长度大于等于ngam_token_size,那么这个查询则转换为一个短语(phrase search),通配符则被忽略。例如,(‘信息*’)转换为(‘”信息”‘),(‘信息系*’)转换为(‘”信息 息系”‘)。

通配符查询示例-2

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

mysql>SELECT *FROM articles WHERE MATCH(title)AGAINST('信息*'INBOOLEANMODE);

+------------+-----------------+

|FTS_DOC_ID|title|

+------------+-----------------+

|1|信息系统|

|2|信息系统|

|3|信息的系统|

|4|信息|

+------------+-----------------+

4rows inset(0.00sec)

mysql>SELECT *FROM articles WHERE MATCH(title)AGAINST('信息系*'INBOOLEANMODE);

+------------+--------------+

|FTS_DOC_ID|title|

+------------+--------------+

|1|信息系统|

+------------+--------------+

1row inset(0.00sec)

短语查询(Phrase Searches)

短语查询则被转换为n-gram分词的短语查询。比如,(‘信息系统’)转换为(‘”信息 息系 系统”‘)。

短语查询示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

mysql>SELECT *FROM articles WHERE MATCH(title)AGAINST('"信息系统"'INBOOLEANMODE);

+------------+--------------+

|FTS_DOC_ID|title|

+------------+--------------+

|1|信息系统|

+------------+--------------+

1row inset(0.00sec)

mysql>SELECT *FROM articles WHERE MATCH(title)AGAINST('"信息 系统"'INBOOLEANMODE);

+------------+---------------+

|FTS_DOC_ID|title|

+------------+---------------+

|2|信息系统|

+------------+---------------+

1row inset(0.01sec)

如果您想了解更多关于InnoDB全文索引的详细内容,可以参考用户手册中InnoDB全文索引的部分,还有Jimmy在Dr. Dobb上的精彩文章。如果您想了解更多关于n-gram的详细内容,则可以参考用户手册中n-gram parser的部分。

我们很高兴在MySQL 5.7全文索引中增强对中日韩文的支持,这也是我们工作中很重要的部分,希望这个功能对大家有帮助。如果您有任何问题,可以在本blog中进行评论,提交一个服务需求,或者提交一个bug报告。

最后,感谢您使用MySQL!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
请帮我翻译每一句代码:def parse_opt(): parser = argparse.ArgumentParser() parser.add_argument('--weights', nargs='+', type=str, default='D://Net//pytorch//yolov5-master//yolov5-master//runs//train//exp3//weights//best.pt', help='model path or triton URL') parser.add_argument('--source', type=str, default=ROOT / 'data/images', help='file/dir/URL/glob/screen/0(webcam)') parser.add_argument('--data', type=str, default=ROOT / 'data/coco128.yaml', help='(optional) dataset.yaml path') parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[480], help='inference size h,w') parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold') parser.add_argument('--iou-thres', type=float, default=0.45, help='NMS IoU threshold') parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image') parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu') parser.add_argument('--view-img', action='store_true', help='show results') parser.add_argument('--save-txt', action='store_true', help='save results to *.txt') parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels') parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes') parser.add_argument('--nosave', action='store_true', help='do not save images/videos') parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --classes 0, or --classes 0 2 3') parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS') parser.add_argument('--augment', action='store_true', help='augmented inference') parser.add_argument('--visualize', action='store_true', help='visualize features')
05-11
def parse_opt(): # 定义 argparse 解析器 parser = argparse.ArgumentParser() # 添加命令行参数 parser.add_argument('--weights', nargs='+', type=str, default='D://Net//pytorch//yolov5-master//yolov5-master//runs//train//exp3//weights//best.pt', help='model path or triton URL') parser.add_argument('--source', type=str, default=ROOT / 'data/images', help='file/dir/URL/glob/screen/0(webcam)') parser.add_argument('--data', type=str, default=ROOT / 'data/coco128.yaml', help='(optional) dataset.yaml path') parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[480], help='inference size h,w') parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold') parser.add_argument('--iou-thres', type=float, default=0.45, help='NMS IoU threshold') parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image') parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu') parser.add_argument('--view-img', action='store_true', help='show results') parser.add_argument('--save-txt', action='store_true', help='save results to *.txt') parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels') parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes') parser.add_argument('--nosave', action='store_true', help='do not save images/videos') parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --classes 0, or --classes 0 2 3') parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS') parser.add_argument('--augment', action='store_true', help='augmented inference') parser.add_argument('--visualize', action='store_true', help='visualize features') # 返回解析器 return parser

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值