Elasticsearch 的 NGram 分词器使用技巧

2021-02-01 01:04:55 浏览数 (1)

一、什么是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": "习中央"
     }
   }
}
//返回为空
match_phrase返回为空match_phrase返回为空

因此,我们需要借用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

0 人点赞