转:https://blog.csdn.net/u011250186/article/details/125704364
1 简介
把输入的文本块按照一定的策略进行分解,并建立倒排索引。在Lucene的架构中,这个过程由分析器(analyzer)完成
2 主要组成
character filter
:接收原字符流,通过添加、删除或者替换操作改变原字符流。例如:去除文本中的html标签,或者将罗马数字转换成阿拉伯数字等。一个字符过滤器可以有零个或者多个
。
tokenizer
:简单的说就是将一整段文本拆分成一个个的词。例如拆分英文,通过空格能将句子拆分成一个个的词,但是对于中文来说,无法使用这种方式来实现。在一个分词器中,有且只有一个
tokenizeer
token filters
:将切分的单词添加、删除或者改变。例如将所有英文单词小写,或者将英文中的停词a
删除等。在token filters
中,不允许将token(分出的词)
的position
或者offset
改变。同时,在一个分词器中,可以有零个或者多个token filters
3 文本分词发生的地方
创建索引
:当索引文档字符类型为text
时,在建立索引时将会对该字段进行分词。
搜索
:当对一个text
类型的字段进行全文检索时,会对用户输入的文本进行分词
4 默认分词器
默认ES使用standard analyzer
,如果默认的分词器无法符合你的要求,可以自己配置
5 查看分词结果语法(测试分词)
5.1 基本用法
1)查询
POST _analyze { "analyzer": "standard", "text": "The quick brown fox" }
2)返回结果
{ "tokens" : [ { "token" : "the", "start_offset" : 0, "end_offset" : 3, "type" : "<ALPHANUM>", "position" : 0 }, { "token" : "quick", "start_offset" : 4, "end_offset" : 9, "type" : "<ALPHANUM>", "position" : 1 }, { "token" : "brown", "start_offset" : 10, "end_offset" : 15, "type" : "<ALPHANUM>", "position" : 2 }, { "token" : "fox", "start_offset" : 16, "end_offset" : 19, "type" : "<ALPHANUM>", "position" : 3 } ] }
5.2 更多用法
同时你也可以按照下面的规则组合使用
- 0个或者多个
character filters
- 一个
tokenizer
- 0个或者多个
token filters
1)查询
POST _analyze { "tokenizer": "standard", "filter": ["lowercase"], "text": "The quick brown fox" }
2)结果
{ "tokens" : [ { "token" : "the", "start_offset" : 0, "end_offset" : 3, "type" : "<ALPHANUM>", "position" : 0 }, { "token" : "quick", "start_offset" : 4, "end_offset" : 9, "type" : "<ALPHANUM>", "position" : 1 }, { "token" : "brown", "start_offset" : 10, "end_offset" : 15, "type" : "<ALPHANUM>", "position" : 2 }, { "token" : "fox", "start_offset" : 16, "end_offset" : 19, "type" : "<ALPHANUM>", "position" : 3 } ] }
与之前不同的是,它会将切分的词进行小写处理。这是因为添加了一个lowercase
的token filter
,它会将分词的词进行小写处理
6 创建mapping时指定分词器示例
对索引和查询都有效
如下,指定ik分词的配置
PUT mytest5 { "mappings": { "properties": { "content": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" } } } }
如果报下面错误,需要安装ik分词器
安装:https://www.cnblogs.com/jthr/p/17075759.html
analyzer [ik_max_word] not found for field [name] kibana
7 配置内置分词器
内置的分词器无需任何配置我们就可以使用。但是我们可以修改内置的部分选项修改它的行为
1)示例
下面的例子中,我们配置分词器std_english
,它使用的分词器为standard
分词器,他的停词列表设置为_english_
.然后字段my_text
使用的是standard
分词器,而字段my_text.english
使用的是我们配置的std_english
DELETE my_index PUT /my_index?pretty { "settings": { "analysis": { "analyzer": { "std_english": { "type": "standard", "stopwords": "_english_" } } } }, "mappings": { "properties": { "my_text": { "type": "text", "analyzer": "standard", "fields": { "english": { "type": "text", "analyzer": "std_english" } } } } } }
2)测试分词
POST /my_index/_analyze?pretty { "field": "my_text", "text": "The old brown cow" }
结果
{ "tokens" : [ { "token" : "the", "start_offset" : 0, "end_offset" : 3, "type" : "<ALPHANUM>", "position" : 0 }, { "token" : "old", "start_offset" : 4, "end_offset" : 7, "type" : "<ALPHANUM>", "position" : 1 }, { "token" : "brown", "start_offset" : 8, "end_offset" : 13, "type" : "<ALPHANUM>", "position" : 2 }, { "token" : "cow", "start_offset" : 14, "end_offset" : 17, "type" : "<ALPHANUM>", "position" : 3 } ] }
测试分词
POST /my_index/_analyze?pretty { "field": "my_text.english", "text": "The old brown cow" }
结果
{ "tokens" : [ { "token" : "old", "start_offset" : 4, "end_offset" : 7, "type" : "<ALPHANUM>", "position" : 1 }, { "token" : "brown", "start_offset" : 8, "end_offset" : 13, "type" : "<ALPHANUM>", "position" : 2 }, { "token" : "cow", "start_offset" : 14, "end_offset" : 17, "type" : "<ALPHANUM>", "position" : 3 } ] }
结果1和2的区别为,结果2中的停词The
被删除,而结果1中的并没有。这是因为my_text.english
配置了停词
8 创建自定义分词器
8.1 简介
当内置的分词器无法满足需求时,可以创建custom
类型的分词器。
tokenizer
:内置或定制的tokenizer.(必须)char_filter
:内置或定制的char_filter(非必须)filter
:内置或定制的token filter(非必须)position_increment_gap
:当值为文本数组时,设置改值会在文本的中间插入假空隙。设置该属性,对与后面的查询会有影响。默认该值为100
8.2 示例
下面的示例中定义了一个名为my_custom_analyzer
的分词器,该分词器的type
为custom
,tokenizer
为standard
,char_filter
为hmtl_strip
,filter
定义了两个分别为:lowercase
和asciifolding
DELETE my_index PUT my_index { "settings": { "analysis": { "analyzer": { "my_custom_analyzer":{ "type":"custom", "tokenizer":"standard", "char_filter":["html_strip"], "filter":["lowercase","asciifolding"] } } } } }
分词测试
POST my_index/_analyze { "text": "Is this <b>déjà vu</b>?", "analyzer": "my_custom_analyzer" }
结果
{ "tokens" : [ { "token" : "is", "start_offset" : 0, "end_offset" : 2, "type" : "<ALPHANUM>", "position" : 0 }, { "token" : "this", "start_offset" : 3, "end_offset" : 7, "type" : "<ALPHANUM>", "position" : 1 }, { "token" : "deja", "start_offset" : 11, "end_offset" : 15, "type" : "<ALPHANUM>", "position" : 2 }, { "token" : "vu", "start_offset" : 16, "end_offset" : 22, "type" : "<ALPHANUM>", "position" : 3 } ] }
9 创建索引自定义分词器并指定给字段示例
1)自定义分词器并为字段指定该分词器
下面操作我们自定义了一个分词器叫做std_folded
,它的tokenizer
为standard
,同时有两个token filter
分别为:lowercase
和asiciifolding
我们在定义mapping时,设置了一个字段名为my_text
,它的类型为text
,我们指定它使用的分词器为我们定义的std_folded
.在分词测试中
PUT /my_index?pretty { "settings": { "analysis": { "analyzer": { "std_folded": { "type": "custom", "tokenizer": "standard", "filter": [ "lowercase", "asciifolding" ] } } } }, "mappings": { "properties": { "my_text": { "type": "text", "analyzer": "std_folded" } } } }
2)测试下该分词器的分词
GET /my_index/_analyze?pretty { "analyzer": "std_folded", "text": "Is this déjà vu?" }
返回结果
{ "tokens" : [ { "token" : "is", "start_offset" : 0, "end_offset" : 2, "type" : "<ALPHANUM>", "position" : 0 }, { "token" : "this", "start_offset" : 3, "end_offset" : 7, "type" : "<ALPHANUM>", "position" : 1 }, { "token" : "deja", "start_offset" : 8, "end_offset" : 12, "type" : "<ALPHANUM>", "position" : 2 }, { "token" : "vu", "start_offset" : 13, "end_offset" : 15, "type" : "<ALPHANUM>", "position" : 3 } ] }
10 创建索引时指定分词器
10.1 简介
如果设置手动设置了分词器,ES将按照下面顺序来确定使用哪个分词器:
- 先判断字段是否有设置分词器,如果有,则使用字段属性上的分词器设置
- 如果设置了
analysis.analyzer.default
,则使用该设置的分词器 - 如果上面两个都未设置,则使用默认的
standard
分词器
10.2 为字段指定分词器
PUT my_index { "mappings": { "properties": { "title":{ "type":"text", "analyzer": "whitespace" } } } }
10.3 为索引设置默认分词器
PUT my_index { "settings": { "analysis": { "analyzer": { "default":{ "type":"simple" } } } } }
11 搜索时如何确定分词器
11.1 简介
在搜索时,通过下面参数依次检查搜索时使用的分词器:
- 搜索时指定
analyzer
参数 - 创建mapping时指定字段的
search_analyzer
属性 - 创建索引时指定
setting
的analysis.analyzer.default_search
- 查看创建索引时字段指定的
analyzer
属性
如果上面几种都未设置,则使用默认的standard
分词器。
11.2 搜索时指定analyzer查询参数
GET my_index/_search { "query": { "match": { "message": { "query": "Quick foxes", "analyzer": "stop" } } } }
11.3 指定字段的seach_analyzer
PUT my_index { "mappings": { "properties": { "title":{ "type":"text", "analyzer": "whitespace", "search_analyzer": "simple" } } } }
11.4 指定索引的默认搜索分词器
PUT my_index { "settings": { "analysis": { "analyzer": { "default":{ "type":"simple" }, "default_seach":{ "type":"whitespace" } } } } }
上面指定创建索引时使用的默认分词器为simple
分词器,而搜索的默认分词器为whitespace
分词器