Elasticsearch N-gram分词器介绍 (7)
一.概述
Ngram是一种基于统计语言模型的算法。Ngram基本思想是将文本里面的内容按照字节大小进行滑动窗口操作,形成长度是N的字节片段序列。此时每一个字节片段称为gram。对所有gram的出现频度进行统计,并且按照事先设定好的阈值进行过滤,形成关键gram列表,也就是这个文本的向量特征空间。列表中的每一种gram就是一个特征向量维度。
应用场景:
1)要分词的文本是:没有空格,没有停用词,无分隔符,或属于行业术语的文本等。
例如:元器件行业型号:bu406, 搜索关键词 ”u40“ 希望能搜索到bu406的型号文档。
无分隔符的手机号码13692345603,搜索关键词”9234“ 希望能搜索到13692345603的手机号文档,可提高检索效率(相较于wildcard检索和正则匹配检索来说)。
2)要求输入搜索的关键词高亮显示。
使用Ngram分词,结合match或者match_phrase检索实现。
3)大数据量下,要求支持左右匹配的模糊搜索,不建议使用wildcrad匹配。
使用Ngram分词以(存储)空间来换(检索)时间。
分词示例:
下面示例使用ngram的默认配置来分词, gram最小长度为1 ,gram最大长度为2
POST _analyze { "tokenizer": "ngram", "text": "Quick Fox" }
分词结果:[ Q, Qu, u, ui, i, ic, c, ck, k, "k ", " ", " F", F, Fo, o, ox, x ]
二. Naram配置
分词器接收以下参数:
1)min_gram: 以gram为单位的最小字符长度,默认值为 1
2)max_gram:以gram为单位的最大字符长度,默认值为 2
3)token_chars:令牌(分词结果)中包含的字符类型,默认是全部类型。字符类型可以是以下几种类型:
letter ---保留字母类型,如a,b,c, 京
digit ---保留数字类型,如1,2
whitespace ---保留空格类型,如 " "
or "\n"
punctuation ---保留标点类型,如 !
or "
symbol ---保留符号类型,如 $
or √
custom ---保留自定义类型,使用custom_token_chars设置自定义的字符
4)custom_token_chars:自定义的字符将视为令牌的一部分
注意:将 min_gram 和 max_gram 设置为相同的值通常是有意义的。
min_gram值越小,匹配的文档就越多,但匹配出来的文档相关性质量就越低。
max_gram值越长, 匹配的文档就越少,但匹配出来的文档相关性质量就越高。
通常:min_gram 长度为 3是一个很好的起点。
索引级别max_ngram_diff参数控制最大允许的差异,max_gram的值不能超过。
三.配置示例
示例1
在此示例中,将分词器配置保留letter,digit二种类型,并设置min_gram和max_gram都为 3
PUT my-index-000001 { "settings": { "analysis": { "analyzer": { "my_analyzer": { "tokenizer": "my_tokenizer" } }, "tokenizer": { "my_tokenizer": { "type": "ngram", "min_gram": 3, "max_gram": 3, "token_chars": [ "letter", "digit" ] } } } } }
分词示例
POST my-index-000001/_analyze { "analyzer": "my_analyzer", "text": "2 Quick Foxes." }
分词结果:[ Qui, uic, ick, Fox, oxe, xes ]
示例2
与示例1不同的是min_gram值为1,max_gram值为3,当二种不同时,必需要设置index.max_ngram_diff 参数值
PUT my-index-000001 { "settings": { "index.max_ngram_diff":3, "analysis": { "analyzer": { "my_analyzer": { "tokenizer": "my_tokenizer" } }, "tokenizer": { "my_tokenizer": { "type": "ngram", "min_gram": 1, "max_gram": 3, "token_chars": [ "letter", "digit" ] } } } } }
分词示例
POST my-index-000001/_analyze { "analyzer": "my_analyzer", "text": "2 Quick Foxes." }
分词结果:[2,Q,Qu,Qui,u,ui,uic,i,ic,ick,c,ck,k,Fo,Fox,o,ox,oxe,x,xe,xes,e,es,s]
示例3
高亮显示示例
PUT my-index-000001 { "settings": { "index.max_ngram_diff":3, "analysis": { "analyzer": { "my_analyzer": { "tokenizer": "my_tokenizer" } }, "tokenizer": { "my_tokenizer": { "type": "ngram", "min_gram": 1, "max_gram": 3, "token_chars": [ "letter", "digit" ] } } } }, "mappings": { "properties": { "remark":{ "type": "text", "analyzer": "my_analyzer" } } } }
插入一个文档
post my-index-000001/_doc { "remark": "2 Quick Foxes." }
搜索关键词并高亮显示,实现了模糊搜索的功能
get my-index-000001/_search { "highlight":{ "fields": { "remark": {} } }, "query":{ "match": { "remark": "uic" } } }
搜索结果如下:
{ "took" : 1304, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 1.7260926, "hits" : [ { "_index" : "my-index-000001", "_type" : "_doc", "_id" : "DPs3wo4B-QCTFG8xdKKR", "_score" : 1.7260926, "_source" : { "remark" : "2 Quick Foxes." }, "highlight" : { "remark" : [ "2 Q<em>u</em><em>i</em><em>c</em>k Foxes." ] } } ] } }
参考官方资料:N-gram tokenizer