一、什么是NGram 分词器?
NGram分词器是ES自带的具有前缀匹配搜索功能的一个文本分词器。它能根据文本的步长逐步对写入的文本内容进行约束切割;
二、NGram和index-time搜索推荐原理
搜索的时候,不用再根据一个前缀,然后扫描整个倒排索引了,而是简单的拿前缀去倒排索引中匹配即可,如果匹配上了,那么就好了,就和match query全文检索一样。
官方介绍如下:
链接:https://www.elastic.co/guide/en/elasticsearch/reference/6.8/analysis-ngram-tokenizer.html
代码语言:javascript复制eg: quick 为列:
Length 1 (unigram): [ q, u, i, c, k ]
Length 2 (bigram): [ qu, ui, ic, ck ]
Length 3 (trigram): [ qui, uic, ick ]
Length 4 (four-gram): [ quic, uick ]
Length 5 (five-gram): [ quick ]
三、NGram分词实践
1,定义一个索引,并指定分词器ngram;
代码语言:javascript复制PUT db_content_testserver2
{
"settings": {
"analysis": {
"analyzer": {
"ngram_analyzer": {
"tokenizer": "ngram_tokenizer"
}
},
"tokenizer": {
"ngram_tokenizer": {
"type": "ngram",
"min_gram": 1,
"max_gram": 5,
"token_chars": [
"letter",
"digit"
]
}
}
}
}
}
2, 创建type,并指定content 字段分词器为"ngram_analyzer"
代码语言:javascript复制PUT db_content_testserver2/_mapping/t_article
{
"properties": {
"content": {
"type": "text",
"analyzer": "ngram_analyzer"
}
}
}
3, 写入测试数据
代码语言:javascript复制POST db_content_testserver2/t_article
{
"content":"据记者了,郑州文化馆、河南省大河文化艺术中心自2016年以来,通过组织第十一届、第十二届中国郑州国际少林武术节书画展,通过书画展文化艺术搭台,是认真贯彻习中央文艺工作座谈会重要讲话精神,响应文化部开展深入生活、扎根人民主题实践活动。以作品的真善美陶冶人类崇高之襟怀品格,树立中华民族的文化自信,用写意精神推动社会文学艺术的繁荣发展。"
}
4,我们可以测试一下上面的分词,是否能正常分词;
代码语言:javascript复制POST db_content_testserver2/_analyze
{
"analyzer": "ngram_analyzer",
"text": "据记者了,郑州文化馆、河南省大河文化艺术中心自2016年以来,通过组织第十一届、第十二届中国郑州国际少林武术节书画展,通过书画展文化艺术搭台,是认真贯彻习中央文艺工作座谈会重要讲话精神,响应文化部开展深入生活、扎根人民主题实践活动。以作品的真善美陶冶人类崇高之襟怀品格,树立中华民族的文化自信,用写意精神推动社会文学艺术的繁荣发展。"
}
四、NGram分词与Match、Match_phrase的实际使用问题
- 上面的案例中,我们通过使用配置ngram分词可以正常切词,能够将上面的内容按照最小为1,最大 为5的原则依次去切割组合成不同的词。那么问题来了,我们究竟在进行搜索的时候, 是用match、还是match_phrase呢?
看使用场景:
1,match
是全文匹配,也就是模糊匹配。只要你输入的内容能匹配上任何一个分词此项,就能将文档返回。但是 match是全文匹配,只要一个字一样,就会返回,错误召回率太高。match 的特点就是召回率高,对于严格匹配的用户不太建议使用此方式。
2,match_phrase
短语匹配,查询比较严格,查询的精度较高。一般需要跟slop 便宜量配合使用,增加召回成功率。比如:match_phrase,搜 深圳无结果, 搜 深圳5G应用遍地开花 有结果,客户需要使用这个方式才能满足业务场景。
match_phrase:短语匹配
含义:相比match,更强调多个分词结果和顺序,都要完整匹配才能检索到。
场景:实战应用中会较多使用,结合slop调整顺序和精度
两种方式对比:
代码语言:javascript复制GET /db_content_testserver2/t_article/_search
{
"query" : {
"match": {
"content": "习中央"
}
}
}
//能正常返回文档
代码语言:javascript复制GET /db_content_testserver2/t_article/_search
{
"query" : {
"match_phrase": {
"content": "习中央"
}
}
}
//返回为空
因此,我们需要借用slop偏移量来解决这个精确搜索返回为空的问题。
代码语言:javascript复制GET db_content_testserver2/t_article/_search
{
"query": {
"match_phrase": {
"content": {
"query":"习中央",
"slop": 6 //偏移量
}
}
}
}
于是这样就能正常返回。
说到这里,客户还问“不同的数据,搜索词,需要的slop不一致,这个在搜索的代码里,无法指定,也不能通过代码取提前算。“
建议用户,如要使用此方法:
”回到数据中去,看用户的query都长啥样,结合你的文档来调整,这就跟算法调参一样,是个不停迭代的结果“
至此,通过以上调试,就彻底解决了客户ngram分词 match_phrase组合使用遇到的使用问题。
鸣谢链接:
https://blog.csdn.net/rick_123/article/details/6708527
https://www.cnblogs.com/buxizhizhoum/p/9874703.html
https://blog.csdn.net/sinat_29581293/article/details/81486761
https://www.imooc.com/article/18578?block_id=tuijian_wz
https://www.elastic.co/guide/en/elasticsearch/reference/6.8/analysis-ngram-tokenizer.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-stop-tokenfilter.html