0%

elasticsearch分析器

Elasticsearch 分析器(Analyzer):文本处理的核心引擎

分析器是 Elasticsearch 处理文本的核心组件,负责将原始文本转换为可索引的词项(Term),直接影响索引质量和搜索准确性。它由字符过滤器(Character Filter)分词器(Tokenizer)分词过滤器(Token Filter) 三部分按顺序协同工作,形成完整的文本处理流水线。

分析器的核心组成与工作流程

组成部分及作用

分析器的三个组件按以下顺序执行操作:

1
原始文本 → 字符过滤器 → 分词器 → 分词过滤器 → 可索引词项
  • 字符过滤器(Character Filter)
    • 作用:对原始文本进行预处理(添加、删除、替换字符),如去除 HTML 标签、替换表情符号。
    • 执行时机:在分词前处理整个文本。
    • 数量:可配置 0 个或多个(按顺序执行)。
  • 分词器(Tokenizer)
    • 作用:将处理后的文本拆分为独立的词项(Token),如按空格、标点拆分。
    • 执行时机:字符过滤后,是分析器的核心拆分步骤。
    • 数量:必须且只能配置 1 个(分词是文本处理的基础)。
  • 分词过滤器(Token Filter)
    • 作用:对分词后的词项进行二次处理(如转小写、去除停用词、添加同义词)。
    • 执行时机:分词后,对每个词项逐个处理。
    • 数量:可配置 0 个或多个(按顺序执行)。

触发时机

分析器在两个阶段工作:

  • 索引时:当文档的 text 类型字段被索引时,分析器将字段值转换为词项并写入倒排索引。
  • 搜索时:当对 text 类型字段执行全文检索时,分析器将查询文本转换为词项,用于匹配索引中的词项。

内置组件详解

Elasticsearch 提供了丰富的内置组件(字符过滤器、分词器、分词过滤器),可直接组合使用或自定义分析器。

内置分析器(Analyzer)

分析器是上述三个组件的组合,内置分析器已预配置好组件,可直接使用:

分析器名称 组成(字符过滤器 + 分词器 + 分词过滤器) 特点与适用场景
standard(默认) 无字符过滤器 + standard 分词器 + 小写过滤器 + 停用词过滤器 通用分析器,适用于大多数语言(英文为主)
simple 无字符过滤器 + letter 分词器(按非字母拆分) + 小写过滤器 简单拆分,适合纯字母文本
whitespace 无字符过滤器 + whitespace 分词器(按空格拆分) + 无过滤器 保留原始大小写和标点,适合精确空格分隔的场景
stop 无字符过滤器 + letter 分词器 + 小写过滤器 + 停用词过滤器 去除常见停用词(如 “the”“的”),减少噪声
keyword 无字符过滤器 + keyword 分词器(不拆分) + 无过滤器 将整个文本作为单个词项,适合精确匹配(如 ID)
pattern 无字符过滤器 + 正则分词器 + 可配置过滤器 按自定义正则表达式拆分,适合结构化文本(如日志)
语言分析器(如 english 针对特定语言优化(如英文词干提取) 适合特定语言的精细化处理

常用内置分词器(Tokenizer)

分词器负责拆分文本,常用类型:

  • standard:默认分词器,按 Unicode 标准拆分(字母、数字为词,其他为分隔符),支持多语言。
  • whitespace:仅按空格(空格、制表符、换行符)拆分,不处理标点(如 “hello,world” 拆分为 “hello,world”)。
  • letter:按非字母字符拆分(如 “hello-world” 拆分为 “hello”“world”)。
  • lowercase:结合 letter 分词器和小写过滤器(拆分后自动转小写)。
  • keyword:不拆分文本,将整个字符串作为单个词项(如 “2023-01-01” 保留原样)。
  • pattern:按自定义正则表达式拆分(如用 [,.] 按逗号或句号拆分)。

常用内置分词过滤器(Token Filter)

分词过滤器处理拆分后的词项,常用类型:

  • lowercase:将词项转为小写(如 “Hello”→“hello”),实现大小写不敏感搜索。
  • stop:去除停用词(如英文 “the”“is”,中文 “的”“了”),减少索引体积。
  • length:过滤长度超出范围的词项(如保留 2-10 个字符的词)。
  • stemmer:提取词干(如英文 “running”→“run”,“cats”→“cat”),统一词的不同形态。
  • synonym:替换同义词(如 “单车”→“自行车”),扩展搜索范围。
  • trim:去除词项前后的空白字符(如 “test”→“test”)。

常用内置字符过滤器(Character Filter)

字符过滤器预处理原始文本,常用类型:

  • html_strip:去除 HTML 标签(如 <b>test</b>→“test”)。
  • mapping:替换指定字符(如将 “:)” 替换为 “happy”)。
  • pattern_replace:按正则表达式替换字符(如将 “2023/01/01” 替换为 “2023-01-01”)。

自定义分析器

当内置分析器无法满足需求时,可通过组合字符过滤器、分词器和分词过滤器自定义分析器,步骤如下:

定义自定义分析器

在索引的 settings 中配置分析器的组件:

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
PUT my_index
{
"settings": {
"analysis": {
"analyzer": {
"my_custom_analyzer": { // 自定义分析器名称
"type": "custom", // 声明为自定义类型
"char_filter": ["html_strip", "emoticons"], // 字符过滤器(按顺序执行)
"tokenizer": "standard", // 分词器
"filter": ["lowercase", "english_stop"] // 分词过滤器(按顺序执行)
}
},
// 自定义字符过滤器(如需)
"char_filter": {
"emoticons": { // 自定义字符过滤器名称
"type": "mapping",
"mappings": [":) => _happy_", ":(" => _sad_"] // 替换表情符号
}
},
// 自定义分词过滤器(如需)
"filter": {
"english_stop": { // 自定义停用词过滤器
"type": "stop",
"stopwords": "_english_" // 使用内置英文停用词表
}
}
}
},
"mappings": {
"default": {
"properties": {
"content": {
"type": "text",
"analyzer": "my_custom_analyzer" // 为字段应用自定义分析器
}
}
}
}
}

测试分析器

使用 _analyze API 验证分析器效果:

1
2
3
4
5
POST my_index/_analyze
{
"analyzer": "my_custom_analyzer", // 要测试的分析器
"text": "<p>Hello :) World!</p>" // 测试文本
}

输出结果(处理后的词项):

1
2
3
4
5
6
7
{
"tokens": [
{"token": "hello", "start_offset": 3, "end_offset": 8, "position": 0},
{"token": "_happy_", "start_offset": 9, "end_offset": 11, "position": 1},
{"token": "world", "start_offset": 13, "end_offset": 18, "position": 2}
]
}

中文分析器:IK Analyzer

Elasticsearch 内置分析器对中文支持有限(通常按单字拆分),需使用第三方插件 IK Analyzer 实现中文分词。

特点与模式

IK 提供两种分词模式:

  • ik_max_word:最细粒度拆分(如 “张三丰打太极”→“张三丰、张三、三、丰、打、太极”),适合精准匹配。
  • ik_smart:最粗粒度拆分(如 “张三丰打太极”→“张三丰、打、太极”),适合短语查询。

安装与配置

  • 安装:下载与 ES 版本匹配的 IK 插件,解压至 plugins/ik 目录,重启 ES 即可。github地址

  • 扩展字典 / 停用词:修改plugins/ik/config/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>

使用示例

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

输出结果(部分):

1
2
3
4
5
6
7
8
9
10
{
"tokens": [
{"token": "张三丰", "start_offset": 0, "end_offset": 3, "position": 0},
{"token": "张三", "start_offset": 0, "end_offset": 2, "position": 1},
{"token": "三", "start_offset": 0, "end_offset": 1, "position": 2},
{"token": "丰", "start_offset": 2, "end_offset": 3, "position": 3},
{"token": "打", "start_offset": 3, "end_offset": 4, "position": 4},
{"token": "太极", "start_offset": 4, "end_offset": 6, "position": 5}
]
}

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

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10