elasticsearch中分词器edge_ngram和ngram的区别

参考:https://www.phpmianshi.com/?id=199

简介

edge_ngram和ngram是ElasticSearch自带的两个分词器,一般设置索引映射的时候都会用到,设置完步长之后,就可以直接给解析器analyzer的tokenizer赋值使用。

场景

用 Elasticsearch 处理通配符查询不太适合,推荐用分词器 NGram,这个分词器可以让通配符查询和普通的查询一样迅速,因为该分词器在数据索引阶段就把所有工作做完了

示例

若要使用 NGram 分词器作为某个字段的分词器,可在索引创建时指定,也可以更新映射关系,以下展示如何在索引创建时指定 NGram 分词器。

{
    "settings": {
        "analysis": {
            "analyzer": {
                "ngram_analyzer": {
                    "tokenizer": "ngram_tokenizer"
                }
            },
            "tokenizer": {
                "ngram_tokenizer": {
                    "type": "ngram",
                    "min_gram": 1,
                    "max_gram": 30,
                    "token_chars": [
                        "letter",
                        "digit"
                    ]
                }
            }
        }
    },
    "mappings": {
        "_default_": {
            "properties": {
                "Name": {
                    "type": "string",
                    "analyzer": "ngram_analyzer"
                }
            }
        }
    }
}

 

当某个字段的 analyzer 被指定为 ngram_analyzer,这个字段的查询就都会变成通配符查询,无论是 term 还是 match。

比如

POST /my_index/_search
{
    "query": {
        "term": {
            "Name": "工商"
        }
    }
}

会得到"中国工商银行XXX分行"。

比如

POST /my_index/_search
{
    "query": {
        "match": {
            "Name": "工商"
        }
    }
}

会得到"中国工商银行XXX分行"、"工行XXX分行"、"中国招商银行XXX分行"。
match 查询会对关键词进行分词,而 Lucene 的默认中文分词就是把每个中文字拆开,这样会变成对"工"、"商"两个字做通配符查询。

 

分词器edge_ngram和ngram的区别

我们统一用字符串来做分词示例:

edge_ngram分词器,分词结果如下:

{
    "tokens": [{
            "token": "字",
            "start_offset": 0,
            "end_offset": 1,
            "type": "word",
            "position": 0
        },
        {
            "token": "字符",
            "start_offset": 0,
            "end_offset": 2,
            "type": "word",
            "position": 1
        },
        {
            "token": "字符串",
            "start_offset": 0,
            "end_offset": 3,
            "type": "word",
            "position": 2
        }
    ]
}

 

ngram分词器,分词结果如下:

{
    "tokens": [{
            "token": "字",
            "start_offset": 0,
            "end_offset": 1,
            "type": "word",
            "position": 0
        },
        {
            "token": "字符",
            "start_offset": 0,
            "end_offset": 2,
            "type": "word",
            "position": 1
        },
        {
            "token": "字符串",
            "start_offset": 0,
            "end_offset": 3,
            "type": "word",
            "position": 2
        },
        {
            "token": "符",
            "start_offset": 1,
            "end_offset": 2,
            "type": "word",
            "position": 3
        },
        {
            "token": "符串",
            "start_offset": 1,
            "end_offset": 3,
            "type": "word",
            "position": 4
        },
        {
            "token": "串",
            "start_offset": 2,
            "end_offset": 3,
            "type": "word",
            "position": 5
        }
    ]
}

 

总结

edge_ngram的分词器,就是从首字开始,按步长,逐字符分词,直至最终结尾文字;

ngram呢,就不仅是从首字开始,而是逐字开始按步长,逐字符分词。

 

很显然这样的分词会几何倍数的消耗磁盘空间,设置不合适也会极大的降低查询性能,所以合适的长度是使用ngram的关键。

 

具体应用呢?如果必须首字匹配的情况,那么用edge_ngram自然是最佳选择,如果需要文中任意字符的匹配,ngram就更为合适了。当然,涉及到中文分词的话,有一些可用的分词插件,不在本文讨论范围。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值