《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.2.Elasticsearch基础应用——3.4.2.17.Text analysis, settings 及 mappings——3.4.2.17.4.Analyzers / Custom analyzers(11) https://developer.aliyun.com/article/1229762
自定义分词器
虽然 Elasticsearch 内置了普通处理方式的分词器,但对于不同的业务场景,当内置的分词器不能满足时,我们可以创建 custom 类型的自定义分词器。根据前面拆解分词器的章节中我们知道一个分词器是由三部分组成,而自定义分词器就是通过在每个阶段选择不同的 filter 进行排列组合来实现的。
自定义实现一个分词器
自定义分词器需要在索引建立时同时创建,组合一个自定义分词器需要满足以下三个条件:
l 0或多个 character filter
l 1个 tokenizer
l 0或多个 token filters
配置项
type 分词器类型,自定义分词器使用 custom。
tokenizer(必填项)文本切分方式,内置 tokenizer 参考。
char_filter(非必填)指定字符过滤器数组。
filter(非必填)指定单词过滤器数组。
position_increment_gap(非必填,默认100)设置 text 数组中每一个元素首尾增加的间隔。这个设置为了避免查询时当两个不同元素的收尾满足查询条件时匹配。
下面的例子创建了一个名为 format_name 的分词器实现把文本中连接线和下划线剔除并转换小写,返回分词结果中第一个单词。分词器配置的过滤器包括:
l Character Filter
○ Mapping Character Filter,将连接线和下划线剔除,过滤器命名为 remove_symbol。
l Tokenizer
○ standard Tokenizer,标准分词器。
l Token Filter
○ Lowercase Token Filter,单词转换为小写字母。
○ Limit Token Filter,配置只返回结果第一个单词,过滤器命名为 first_word 。
PUT test-000001 { "settings": { "analysis": { "analyzer": { "format_name": { #1 "type": "custom", "char_filter": [ "remove_symbol" #2 ], "tokenizer": "standard", 761 > 三、产品能力 "filter": [ "lowercase", #3 "first_word" ] } }, "char_filter": { "remove_symbol": { #2-1 "type": "mapping", "mappings": [ "- => ", "_ => " ] } }, "filter": { "first_word": { #3-1 "type": "limit", "max_token_count": 1 } } } } } POST test-000001/_analyze { "analyzer": "format_name", "text": [ "Spider-Man 1", "Spider_Man 2", "SpiderMan: 3" ] }
#1 自定义过滤器 format_name。
#2 使用 remove_symbol 过滤器进行字符串过滤,根据 Mapping Character Filter 配置得到,需要在 analysis > char_filter 中定义。
#2-1 配置滤器命名为 remove_symbol。
#3 使用 lowercase 转换小写和 first_word 返回第一个单词。first_word 根据 Limit token count filter 配置得到,需要在 analysis > filter 中定义。
#3-1 配置过滤器命名为 first_word。
通过 _analyze 实验我们可以看到三个不同的字符串经过处理将返回相同的内容,从而保证在搜索时都能匹配到。
{ "tokens" : [ { "token" : "spiderman", "start_offset" : 0, "end_offset" : 10, "type" : "<ALPHANUM>", "position" : 0 }, { "token" : "spiderman", "start_offset" : 11, "end_offset" : 21, "type" : "<ALPHANUM>", "position" : 101 }, { "token" : "spiderman", "start_offset" : 22, "end_offset" : 31, "type" : "<ALPHANUM>", "position" : 202 } ] }
为指定字段使用分词器
分词器使用最常见的情况是设置在指定的字段上,通常是针对某一字段的写入或者检索前进行需要分词的处理。而为文本字段指定分词器是在索引创建时发生,在 mapping 中设置文本字段的 analyzer 参数。 下面创建索引请求中设置 movie_name 字段使用 whitespace 分词器。
PUT test-000001 { "mappings": { "properties": { "movie_name": { "type": "text", "analyzer": "whitespace" } } }
获取文件的类型。当需要根据文件类型搜索时,我们可以通过子字段 file_name.ext 进行匹配。
PUT test-000001 { "settings": { "analysis": { "analyzer": { "ext_type": { "type": "custom", "tokenizer": "keyword", "filter": [ "file_ext" ] } }, "filter": { "file_ext": { "type": "pattern_replace", "pattern": """^(.*)\.""", "replacement": "" } } } }, "mappings": { "properties": { "file_name": { "type": "text", "analyzer": "whitespace", "fields": { "ext": { "type": "text", "analyzer": "ext_type" } } } } } }
根据 _analyze API 测试可以看到,结果返回提取到的文件扩展名。
POST test-000001/_analyze { "field": "file_name.ext", "text": [ "logo.png", "readme.md", "service.login_service.py" ] } { "tokens" : [ { "token" : "png", "start_offset" : 0, "end_offset" : 8, "type" : "word", "position" : 0 }, { "token" : "md", "start_offset" : 9, "end_offset" : 18, "type" : "word", "position" : 101 }, { "token" : "py", "start_offset" : 19, "end_offset" : 43, "type" : "word", "position" : 202 } ] }
《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.2.Elasticsearch基础应用——3.4.2.17.Text analysis, settings 及 mappings——3.4.2.17.4.Analyzers / Custom analyzers(13) https://developer.aliyun.com/article/1229756