《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.2.Elasticsearch基础应用——3.4.2.17.Text analysis, settings 及 mappings——3.4.2.17.4.Analyzers / Custom analyzers(1) https://developer.aliyun.com/article/1229776
Analyze API
Elasticsearch 提供了 _analyze API 用于查看分词器是如何解析文本内容的。如果需要为索引中的文本字段指定分词器,在创建前可以使用 _analyze 来测试分词器是否满足业务场景的需要。下面的例子使用 whitespace 分词器对字符串分词。
POST _analyze { "analyzer": "whitespace", "text": ["This is a test"] }
响应结果就是文本经过分词器处理后的单词数组,除了返回每个单词外同时也包含了起始位置和单词在文本中的位置。
{ "tokens" : [ { "token" : "This", "start_offset" : 0, "end_offset" : 4, "type" : "word", "position" : 0 }, { "token" : "is", "start_offset" : 5, "end_offset" : 7, "type" : "word", "position" : 1 }, { "token" : "a", "start_offset" : 8, "end_offset" : 9, "type" : "word", "position" : 2 }, { "token" : "test", "start_offset" : 10, "end_offset" : 14, "type" : "word", "position" : 3 } ] }
API 中除了指定 analyzer 属性对 Elasticsearch 中现有的分词器进行测试外,也可以对分词器三个组成部分 Character filters,Tokenizer,Token filters 进行自定义组合配置,这在创建自定义分词器前非常有用。通过底层自定义过滤器组合测试需要注意和 analyzer 之间为互斥关系,两种分词方式只能选择一种。
POST _analyze { "tokenizer": "standard", "filter": ["lowercase"], "text": [ "This is a test" ] }
使用了 standard 对文本进行切分,切分后结果转小写。
{ "tokens" : [ { "token" : "this", "start_offset" : 0, "end_offset" : 4, "type" : "<ALPHANUM>", "position" : 0 }, { "token" : "is", "start_offset" : 6, "end_offset" : 8, "type" : "<ALPHANUM>", "position" : 1 }, { "token" : "a", "start_offset" : 9, "end_offset" : 10, "type" : "<ALPHANUM>", "position" : 2 }, { "token" : "test", "start_offset" : 11, "end_offset" : 15, "type" : "<ALPHANUM>", "position" : 3 } ] }
Analyze API 请求方式包括以下四种:
l GET /_analyze
l POST /_analyze
l GET //_analyze
l POST //_analyze
配置参数
index(非必填,字符串)对指定索引的分词器进行测试,通常配合 field 属性使用,实现指定字段的分词器测试。如果不指定 field 或 analyzer,则使用索引默认的分词器,如果索引没有指定默认分词器,将使用 standard 分词器。
analyzer(非必填,字符串)指定分词器对文本内容进行测试,不指定使用索引默认分词器,如果索引没有指定默认分词器,将使用 standard 分词器。如果同时指定了 field 属性,将使用 field 的分词器进行测试。
char_filter(非必填,字符串或字符串数组)配置字符过滤器,对源文本内容进行修改。相关配置在 Character filter 章节列出说明。
tokenizer(非必填,字符串)指定文本的切分方式。相关配置在 Tokenizer 章节列出说明。
filter(非必填,字符串或字符串数组)对切分后的单词数组进行标准化。相关配置在 Tokenfilter 章节列出说明。
field(非必填,字符串) 对索引中指定字段的分词器进行测试,需要指定索引才能使用此参数。如果该字段没有指定分词器将使用索引默认分词器,如果索引没有指定默认分词器,将使用standard 分词器。
text(必填)用于测试分词器的文本。
调用样例
指定分词器解析文本
使用 whitespace 分词器对文本进行分词测试,文本使用空格分割。
POST _analyze { "analyzer": "whitespace", "text": ["This is a test"] } #Response [ This, is, a, test ]
自定义组合分词器解析文本
指定了使用 standard 方式对文本进行切分,结果需要转换小写并使用默认 stop filter 对结果中停用词进行剔除。英文中默认的停用词包括(a,an,and,are)等,具体配置细节可以参考拆解分词器章节 Token filter 下 Stop token filter 的内容。停用词默认按照小写进行匹配,使用时需要注意 filter 是按照定义顺序依次执行,如果转换小写过滤器在停用词之后,就会遗漏大写的停用词。
POST _analyze { "tokenizer": "standard", "filter": [ "lowercase", "stop" ], "text": [ "THIS is a TEST" ] } #Response [ test ]
此时调换一下 filter 的顺序将stop filter 放在 lowercase filter 操作之前进行处理,可以看到大写的 THIS 不会被剔除,而是转换为了小写保留。
POST _analyze { "tokenizer": "standard", "filter": [ "stop", "lowercase" ], "text": [ "THIS is a TEST" ] } #Resposne [ this , test ]
组合分词器除了指定时过滤器或切分方式的名称外,同时也支持为 char_filter/tokenizer/filter 增加配置。下面的样例指定使用 standard 方式对文本进行切分,结果需要转换小写并且对停用词进行自定义设置。a is this test 四个单词作为停用词,当文本中出现以上四个单词时都将会被剔除。
POST _analyze { "tokenizer": "standard", "filter": [ "lowercase", #1 { "type": "stop", #2 "stopwords": [ "a", "is", "this", "test" ] } ], "text": [ "THIS is a TEST,Test Number is:1234" ] } #Response [ number, 1234 ]
#1 lowercase 小写转换过滤器使用默认配置,直接传递字符串。
#2 stop 停用词过滤器增加了停用词列表的配置,通过 { type:"过滤器名名称","配置属性":"值" } 格式增加配置项。
指定索引下分词器解析文本
使用 sample 索引的分词器对文本进行测试。如果索引没有设置分词器,将使用 standard 分词器。
PUT sample { "mappings": { "properties": { "content": { "type": "text", "analyzer": "keyword" } } } } # 默认使用 standard 分词器进行分词 POST sample/_analyze { "text" : "This is a test" } #Response [ This, is, a, test ]
使用 sample 索引中 content 字段配置的分词器对文本进行测试。content 必须要存在,如果该字段没有指定分词器将使用索引默认分词器,如果索引没有指定默认分词器,将使用
standard 分词器。根据 mapping 中的定义,我们指定了 content 分词为 keyword 类型,文本内容将会作为整体返回。
POST sample/_analyze { "field": "content", "text": "This is a test" } #Response [ "This is a test" ]
拆解分词器
在写入阶段中我提到了分词器像“管道”,在这小节中我们来拆解分析下这个“管道”每一步都做了什么操作。大体上分词器包括以下三部分。
1、character filter 字符过滤器:对源文本内容进行修改,如替换字符,删除 HTML 标记。是分词器的第一步处理,一个分词其中可以包括多个字符过滤器。
2、tokenizer 字符切分方式:指定文本的切分方式。把接收到文本内容切分成一个个独立的单词,并返回切分后单词对象数组。分词器中只能指定一个切分方式。
3、token filter 单词过滤器:对切分后的单词数组进行标准化。使用不同的过滤器对数组进行增加、修改和删除的操作,分词器中可以包含多个单词过滤器。
Character filter
HTML strip character filter
html_strip 过滤器对文本中 HTML 标签处理。包括剔除 HTML 中的行级标签,\n 换行符替换块级标签,HTML 的转义字符将会转换为 HTML 标签。
POST _analyze { "char_filter": ["html_strip"], #1 "text": [ "<a href='https://www.google.com'>google.com</a>", "<div>block-level element</div>", "<p>" ] }
《Elastic Stack 实战手册》——三、产品能力——3.4.入门篇——3.4.2.Elasticsearch基础应用——3.4.2.17.Text analysis, settings 及 mappings——3.4.2.17.4.Analyzers / Custom analyzers(3) https://developer.aliyun.com/article/1229774