因为Elasticsearch中默认的标准分词器分词器对中文分词不是很友好,会将中文词语拆分成一个一个中文的汉子,因此引入中文分词器。
在ES中一个Analyzer 由下面三种组件组合而成:
- character filter :字符过滤器,对文本进行字符过滤处理,如处理文本中的html标签字符。处理完后再交给tokenizer进行分词。一个analyzer中可包含0个或多个字符过滤器,多个按配置顺序依次进行处理。
- tokenizer:分词器,对文本进行分词。一个analyzer必需且只可包含一个tokenizer。
- token filter:词项过滤器,对tokenizer分出的词进行过滤处理。如转小写、停用词处理、同义词处理。一个analyzer可包含0个或多个词项过滤器,按配置顺序进行过滤。
测试默认的分词
#或 http://127.0.0.1:9200/_analyze1
2
3
4
5GET /_analyze
{
"analyzer":"standard",
"text":"中国china"
}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参数:
{
"analyzer":"standard",
"text":"中国china"
}
结果:
{
"tokens": [
{
"token": "中",
"start_offset": 0,
"end_offset": 1,
"type": "<IDEOGRAPHIC>",
"position": 0
},
{
"token": "国",
"start_offset": 1,
"end_offset": 2,
"type": "<IDEOGRAPHIC>",
"position": 1
},
{
"token": "china",
"start_offset": 2,
"end_offset": 7,
"type": "<ALPHANUM>",
"position": 2
}
]
}
position:第几个词
offset:词的偏移位置character filter
- HTML Strip Character Filter **测试:
1
2
3
4
5
6HTML Strip Character Filter
html_strip :过滤html标签,解码HTML entities like &.
Mapping Character Filter
mapping :用指定的字符串替换文本中的某字符串。
Pattern Replace Character Filter
pattern_replace :进行正则表达式替换。在索引中配置:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24GET _analyze
{
"tokenizer": "keyword",
"char_filter": [ "html_strip" ],
"text": "<p> I <br/> Love <br/> You!</p>"
}
结果:
{
"tokens" : [
{
"token" : """
I
Love
You!
""",
"start_offset" : 0,
"end_offset" : 31,
"type" : "word",
"position" : 0
}
]
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21PUT my_index
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "keyword",
"char_filter": ["my_char_filter"]
}
},
"char_filter": {
"my_char_filter": {
"type": "html_strip",
"escaped_tags": ["b"]
}
}
}
}
}
#escaped_tags 用来指定例外的标签。
- HTML Strip Character Filter **
- Mapping 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
26PUT demo_index
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "keyword",
"char_filter": [
"my_char_filter"
]
}
},
"char_filter": {
"my_char_filter": {
"type": "mapping",
"mappings": [
"零 => 0",
"一 => 1",
"二 => 2",
"三 => 3"
]
}
}
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17POST demo_index/_analyze
{
"analyzer": "my_analyzer",
"text": "一二三四五六零"
}
结果:
{
"tokens" : [
{
"token" : "123四五六0",
"start_offset" : 0,
"end_offset" : 7,
"type" : "word",
"position" : 0
}
]
}
- 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
22PUT demo_index1
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "standard",
"char_filter": [
"my_char_filter"
]
}
},
"char_filter": {
"my_char_filter": {
"type": "pattern_replace",
"pattern": "(\\d+)-(?=\\d)",
"replacement": "$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
45POST demo_index1/_analyze
{
"analyzer": "my_analyzer",
"text": "My credit card is 123-456-789"
}
结果:
{
"tokens" : [
{
"token" : "My",
"start_offset" : 0,
"end_offset" : 2,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "credit",
"start_offset" : 3,
"end_offset" : 9,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "card",
"start_offset" : 10,
"end_offset" : 14,
"type" : "<ALPHANUM>",
"position" : 2
},
{
"token" : "is",
"start_offset" : 15,
"end_offset" : 17,
"type" : "<ALPHANUM>",
"position" : 3
},
{
"token" : "123_456_789",
"start_offset" : 18,
"end_offset" : 29,
"type" : "<NUM>",
"position" : 4
}
]
}Tokenizer
Standard TokenizerKeyword Tokenizer1
2
3
4
5
6
7
8Letter Tokenizer
Lowercase Tokenizer
Whitespace Tokenizer
UAX URL Email Tokenizer
Classic Tokenizer
Thai Tokenizer
NGram Tokenizer
Edge NGram Tokenizer测试:1
2
3
4
5
6
7
8
9Pattern Tokenizer
Simple Pattern Tokenizer
Simple Pattern Split Tokenizer
Path Hierarchy Tokenizer
Keyword Tokenizer
Pattern Tokenizer
Simple Pattern Tokenizer
Simple Pattern Split Tokenizer
Path Hierarchy Tokenizer1
2
3
4
5POST _analyze
{
"tokenizer": "ik_smart",
"text": "中国china"
}
- Pattern Replace Character Filter **
Token Filter
ES中内建了很多Token filter
1 | Lowercase Token Filter :lowercase 转小写 |
** Synonym Token Filter 同义词过滤器 **
1 | PUT /demo_index1 |
ES同义词格式支持 solr、 WordNet 两种格式。
1 | 张三,李四 |
Analyzer
集成的中文分词器Ikanalyzer中提供的Analyzer:ik_smart 、 ik_max_word
内建的和集成的analyzer可以直接使用。如果它们不能满足我们的需要,则我们可自己组合字符过滤器、分词器、词项过滤器来定义自定义的analyzer
自定义 Analyzer
1 | PUT demo_index3{ |
为字段指定分词器
1 | PUT demo_index4/_mapping/user |
如果该字段的查询需要使用不同的analyzer
1 | PUT demo_index4/_mapping/user |
索引定义default分词器
1 | PUT /demo_index4 |
** Analyzer的使用顺序 **
可以为每个查询、每个字段、每个索引指定分词器。
在索引阶段ES将按如下顺序来选用分词:
1 | 首先选用字段mapping定义中指定的analyzer |
The analyzer defined in a full-text query.
The search_analyzer defined in the field mapping.
The analyzer defined in the field mapping.
An analyzer named default_search in the index settings.
An analyzer named default in the index settings.
The standard analyzer.
1 |
|
{
“tokens”: [
{
“token”: “中国”,
“start_offset”: 0,
“end_offset”: 2,
“type”: “CN_WORD”,
“position”: 0
},
{
“token”: “china”,
“start_offset”: 2,
“end_offset”: 7,
“type”: “ENGLISH”,
“position”: 1
}
]
}
1 |
|
IK 5.0 以后,移除名为 ik 的analyzer和tokenizer 只能使用 ik_smart 和 ik_max_word
ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合;
ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”。
1 |
|
1 | 修改配置: |
1 | 就可以在对应位置写一些分词。vi ./custom/new_word.dic 如: |
1 |
|
1 | 结果: |
1 | 新增扩展词后让历史数据生效: |
1 | 在配置文件中,用户可一次配置多个词典文件。文件名使用;号分隔,文件路径为相对 java 包的起始根路径。 |
public static Dictionary getSingleton() //获取初始化完毕的字典单例 返回值:Dictionary IK 词典单例
public void addWords(Collection
public void disableWords(Collection
1 | 示例: |
** 通过java看分词 **
1 | //构造一个IKAnalyzer对象,构造器参数为true说明使用智能分词,默认为最细粒度切分 |