0%

elasticsearch分析器

elasticsearch分析器

索引分析是在文档被发送到倒排索引之前,把一个文本块分析成一个个单独的词,为了后面的倒排索引做准备,然后标准化这些词为标准形式,提高它们的可搜索性,这些工作是分析器完成的,一个分析器是一个组合,用于将三个功能放在一起

  • 字符过滤器(character filter):接收原字符流经过字符过滤器处理,通过添加、删除、替换操作原字符流。它们的工作是在标记化之前处理字符串,字符串过滤器可以去除HTML标记。可以有零个或多个字符过滤器。
  • 分词器(tokenizer):分词器被标记化成独立的词,将一整段文本拆分为一个个的词。一个简单的分词器可以根据空格或逗号分开。有且只有一个分词器。
  • 分词过滤器(token filters):将切分的单词添加、删除或修改。如将所有单词小写。可以有零个或多个分词过滤器。

elasticsearch有很多内置的分析器,也可以自定义分析器

调用顺序为Character Filters->Tokenizer->Token Filters

文本分词触发时机

  • 创建索引时 当索引文档字符类型为text时,在建立索引时将会对该字段进行分词
  • 进行搜索时 当一个text类型的字段进行全文检索时,会对用户输入的文本进行分词

elasticsearch提供的默认分析器有

  • Standard Analyzer 标准分析器,其包括了标准分词器、标准分词过滤器、小写转换分词过滤器和停用词分词过滤器
  • Simple Analyzer 简单分析器,其使用了小写转换分词器
  • Whitespace Analyzer 空格分析器,其使用空格来将文本进行分词
  • Stop Analyzer 停用词分析器
  • Keyword Analyzer 关键词分析器
  • Pattern Analyzer 模式分析器,可以指定一个分词切分的模式
  • Language Analyzers 语言分析器
  • Fingerprint Analyzer

elasticsearch提供的默认分词器有

  • Word Oriented Tokenizers

    • Standard Tokenizer 标准分词器

    • Letter Tokenizer 字母分词器,使用非字母的符号来分词

    • Lowercase Tokenizer 小写分词器,其使用了字母分词器和小写分词过滤器

    • Whitespace Tokenizer 空格分词器,通过空格来进行分词(包括空格、制表符、换行符等)

    • UAX URL Email Tokenizer

    • Classic Tokenizer

    • Thai Tokenizer

  • Partial Word Tokenizers

    • N-Gram Tokenizer
    • Edge N-Gram Tokenizer
  • Structured Text Tokenizers

    • Keyword Tokenizer 关键词分词器
    • Pattern Tokenizer 模式分词器
    • Simple Pattern Tokenizer
    • Char Group Tokenizer
    • Simple Pattern Split Tokenizer
    • Path Tokenizer 路径分词器

默认的分词过滤器有

  • Standard Token Filter 标准分词过滤器

  • ASCII Folding Token Filter

  • Flatten Graph Token Filter

  • Length Token Filter 长度分词过滤器,将超出最短和最长范围的单词过滤掉

  • Lowercase Token Filter 小写分词过滤器

  • Uppercase Token Filter

  • NGram Token Filter

  • Edge NGram Token Filter

  • Porter Stem Token Filter

  • Shingle Token Filter

  • Stop Token Filter 停用词分词过滤器

  • Word Delimiter Token Filter

  • Word Delimiter Graph Token Filter

  • Multiplexer Token Filter

  • Conditional Token Filter

  • Predicate Token Filter Script

  • Stemmer Token Filter

  • Stemmer Override Token Filter

  • Keyword Marker Token Filter

  • Keyword Repeat Token Filter

  • KStem Token Filter

  • Snowball Token Filter

  • Phonetic Token Filter

  • Synonym Token Filter

  • Parsing synonym files

  • Synonym Graph Token Filter

  • Compound Word Token Filters

  • Reverse Token Filter

  • Elision Token Filter

  • Truncate Token Filter 截断分词过滤器,可以通过定制配置中的length参数,来截断超过一定长度的分词

  • Unique Token Filter

  • Pattern Capture Token Filter

  • Pattern Replace Token Filter

  • Trim Token Filter 修剪分词过滤器,删除分词中所有空白部分

  • Limit Token Count Token Filter 限制分词数量分词过滤器,限制了某个字段可包含分词的最大数量,使用max_token_count参数

  • Hunspell Token Filter

  • Common Grams Token Filter

  • Normalization Token Filter

  • CJK Width Token Filter

  • CJK Bigram Token Filter

  • Delimited Payload Token Filter

  • Keep Words Token Filter

  • Keep Types Token Filter

  • Exclude mode settings example

  • Classic Token Filter

  • Apostrophe Token Filter

  • Decimal Digit Token Filter

  • Fingerprint Token Filter

  • MinHash Token Filter

  • Remove Duplicates Token Filter

默认的字符过滤器有

  • HTML Strip Character Filter
  • Mapping Character Filter
  • Pattern Replace Character Filter

内置分析器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
GET _analyze
{
"analyzer":"standard", // 分析器
"text":"test analyze" // 分析的语句
}


// 分析结果
{
"tokens": [
{
"token": "test",
"start_offset": 0,
"end_offset": 4,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "analyze",
"start_offset": 5,
"end_offset": 12,
"type": "<ALPHANUM>",
"position": 1
}
]
}

自定义分析器

自定义分析器可以设置

  • tokenizer 分词器的逻辑
  • char_filter 字符过滤器的逻辑
  • filter 分词过滤器的逻辑
  • position_increment_gap 每个使用本分词字段的字段值之间可增加的位置,默认100
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
POST _analyze
{
"tokenizer": "standard", // 分词器
"filter": [ //分词过滤器
"lowercase" // 转小写
],
"char_filter": [ // 字符过滤器
"html_strip" // 过滤掉html字符
],
"text": "this is my <b>TITLE</b>"
}


// 分析结果
{
"tokens": [
{
"token": "this",
"start_offset": 0,
"end_offset": 4,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "is",
"start_offset": 5,
"end_offset": 7,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "my",
"start_offset": 8,
"end_offset": 10,
"type": "<ALPHANUM>",
"position": 2
},
{
"token": "title",
"start_offset": 14,
"end_offset": 23,
"type": "<ALPHANUM>",
"position": 3
}
]
}

可以使用explain来输出分词器的细节

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
POST _analyze
{
"tokenizer": "standard",
"filter": [
"lowercase"
],
"char_filter": [
"html_strip"
],
"text": "this is my <b>TITLE</b>",
"explain": true
}



{
"detail": {
"custom_analyzer": true,
"charfilters": [
{
"name": "html_strip",
"filtered_text": [
"this is my TITLE"
]
}
],
"tokenizer": {
"name": "standard",
"tokens": [
{
"token": "this",
"start_offset": 0,
"end_offset": 4,
"type": "<ALPHANUM>",
"position": 0,
"bytes": "[74 68 69 73]",
"positionLength": 1,
"termFrequency": 1
},
{
"token": "is",
"start_offset": 5,
"end_offset": 7,
"type": "<ALPHANUM>",
"position": 1,
"bytes": "[69 73]",
"positionLength": 1,
"termFrequency": 1
},
{
"token": "my",
"start_offset": 8,
"end_offset": 10,
"type": "<ALPHANUM>",
"position": 2,
"bytes": "[6d 79]",
"positionLength": 1,
"termFrequency": 1
},
{
"token": "TITLE",
"start_offset": 14,
"end_offset": 23,
"type": "<ALPHANUM>",
"position": 3,
"bytes": "[54 49 54 4c 45]",
"positionLength": 1,
"termFrequency": 1
}
]
},
"tokenfilters": [
{
"name": "lowercase",
"tokens": [
{
"token": "this",
"start_offset": 0,
"end_offset": 4,
"type": "<ALPHANUM>",
"position": 0,
"bytes": "[74 68 69 73]",
"positionLength": 1,
"termFrequency": 1
},
{
"token": "is",
"start_offset": 5,
"end_offset": 7,
"type": "<ALPHANUM>",
"position": 1,
"bytes": "[69 73]",
"positionLength": 1,
"termFrequency": 1
},
{
"token": "my",
"start_offset": 8,
"end_offset": 10,
"type": "<ALPHANUM>",
"position": 2,
"bytes": "[6d 79]",
"positionLength": 1,
"termFrequency": 1
},
{
"token": "title",
"start_offset": 14,
"end_offset": 23,
"type": "<ALPHANUM>",
"position": 3,
"bytes": "[74 69 74 6c 65]",
"positionLength": 1,
"termFrequency": 1
}
]
}
]
}
}

创建索引时使用定制分析器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
PUT /myindex

{
"settings": {
"analysis": {
"analyzer": {
"my_custom_analyzer": { // 分词器名称
"type": "custom", // 自定义分析器
"char_filter": [ // 字符过滤器别名,在下边定义
"emoticons"
],
"tokenizer": "punctuation",// 分词器别名,在下面定义
"filter": [ // 分词过滤器别名,在下边定义
"lowercase",
"english_stop"
]
}
},
"tokenizer": {
"punctuation": { // 自定义的分解词器
"type": "pattern",
"pattern": "[ .,!?]"
}
},
"char_filter": {
"emoticons": { // 自定义的字符过滤器
"type": "mapping",
"mappings": [
":) => _happy_",
":( => _sad_"
]
}
},
"filter": {
"english_stop": { // 自定义的词元过滤器
"type": "stop",
"stopwords": "_english_"
}
}
}
},

"mappings": {
"default": {
"properties": {
"category": {
"type": "text",
"analyzer": "my_custom_analyzer", // 为该字段指定分析器
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"description": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},

"keywords": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"publishTime": {
"type": "long"
},

"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}

中文分析器

github地址

elasticsearch中内置的分析器对中文支持不是很友好,可以使用IKAnanlyzer

ik插件下载之后在elasticsearch的plugins目录下新建一个ik目录,将下载的文件解压到该目录下即可

1
2
3
4
5
GET /_analyze
{
"analyzer":"ik_max_word",
"text":"张三丰打太极"
}

IKAnanlyzer中提供了两种分析器:ik_max_wordik_smart

  • ik_max_word:会将文本做最细粒度的拆分,比如会将“张三丰打太极”拆分为“张三丰 张三 三 丰 打 太极”,会穷尽各种可能的组合,适合Term Query;
  • ik_smart: 会做最粗粒度的拆分,比如会将“张三丰打太极”拆分为“张三丰 打 太极”,适合 Phrase 查询

配置文件IKAnalyzer.cfg.xml(分词器扩展配置文件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典,多个使用分号分隔 -->
<entry key="ext_dict">extra_main.dic;extra_main_first.dic</entry>
<!--用户可以在这里配置自己的扩展停止词字典,多个使用分号分隔-->
<!-- 可以使用该停用词,比自带的多 https://github.com/cseryp/stopwords/blob/master/stopwords.txt -->
<entry key="ext_stopwords">extra_stopword.dic</entry>
<!--用户可以在这里配置远程扩展字典 -->
<!-- <entry key="remote_ext_dict">http://localhost:8080/ext.dic</entry> -->
<!--用户可以在这里配置远程扩展停止词字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

欢迎关注我的其它发布渠道