跳到主要内容

中文分词

中文分词是中文搜索的关键。本章介绍如何在 Elasticsearch 中配置和使用 IK 中文分词器。

分词器概述

为什么需要中文分词?

英文分词:
"The quick brown fox" -> ["the", "quick", "brown", "fox"]
(按空格自然分词)

中文分词:
"搜索技术很强大" -> ?
- 按字分词:["搜", "索", "技", "术", "很", "强", "大"]
- 智能分词:["搜索", "技术", "很", "强大"]
(需要理解语义才能正确分词)

IK 分词器

IK 分词器是最常用的 Elasticsearch 中文分词插件,提供两种分词模式:

  • ik_smart:智能分词,粗粒度,适合搜索时使用
  • ik_max_word:最大化分词,细粒度,适合索引时使用

安装 IK 分词器

在线安装

# 进入 Elasticsearch 插件目录
cd /usr/share/elasticsearch

# 安装插件(版本需要与 ES 版本匹配)
bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.12.0/elasticsearch-analysis-ik-8.12.0.zip

# 重启 Elasticsearch
systemctl restart elasticsearch

Docker 安装

# 创建 Dockerfile
FROM docker.elastic.co/elasticsearch/elasticsearch:8.12.0
RUN bin/elasticsearch-plugin install --batch https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.12.0/elasticsearch-analysis-ik-8.12.0.zip
# 构建镜像
docker build -t elasticsearch-ik:8.12.0 .

验证安装

GET /_cat/plugins

# 响应
elasticsearch-analysis-ik 8.12.0

使用 IK 分词器

测试分词效果

# ik_smart 智能分词
GET /_analyze
{
"analyzer": "ik_smart",
"text": "搜索技术很强大"
}

# 响应
{
"tokens": [
{ "token": "搜索", "position": 0 },
{ "token": "技术", "position": 1 },
{ "token": "很", "position": 2 },
{ "token": "强大", "position": 3 }
]
}

# ik_max_word 最大化分词
GET /_analyze
{
"analyzer": "ik_max_word",
"text": "搜索技术很强大"
}

# 响应
{
"tokens": [
{ "token": "搜索", "position": 0 },
{ "token": "搜索技术", "position": 0 },
{ "token": "技术", "position": 1 },
{ "token": "很", "position": 2 },
{ "token": "强大", "position": 3 }
]
}

解释

  • ik_smart 产生最少的分词结果,适合搜索
  • ik_max_word 尽可能多地分词,适合索引

创建使用 IK 分词器的索引

PUT /articles
{
"settings": {
"analysis": {
"analyzer": {
"ik_smart_analyzer": {
"type": "custom",
"tokenizer": "ik_smart"
},
"ik_max_word_analyzer": {
"type": "custom",
"tokenizer": "ik_max_word"
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word", # 索引时使用细粒度
"search_analyzer": "ik_smart" # 搜索时使用粗粒度
},
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"author": {
"type": "keyword"
}
}
}
}

测试搜索

# 索引文档
POST /articles/_doc
{
"title": "Elasticsearch 搜索技术详解",
"content": "本文详细介绍 Elasticsearch 的搜索技术,包括全文搜索、精确搜索等"
}

# 搜索测试
GET /articles/_search
{
"query": {
"match": {
"title": "搜索技术"
}
}
}

自定义词典

IK 分词器支持自定义词典,添加新词。

配置自定义词典

# 进入 IK 分词器配置目录
cd config/analysis-ik/

# 编辑配置文件
vi IKAnalyzer.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<properties>
<entry key="ext_dict">custom/my_dict.dic</entry>
<entry key="ext_stopwords">custom/my_stopword.dic</entry>
</properties>

创建自定义词典

# 创建自定义词典文件
mkdir -p config/analysis-ik/custom
vi config/analysis-ik/custom/my_dict.dic
# my_dict.dic 内容
Elasticsearch
Kubernetes
云原生
微服务架构

创建停用词词典

vi config/analysis-ik/custom/my_stopword.dic
# my_stopword.dic 内容





远程词典

支持从远程 HTTP 服务加载词典,实现热更新:

<?xml version="1.0" encoding="UTF-8"?>
<properties>
<entry key="remote_ext_dict">http://example.com/dict.txt</entry>
<entry key="remote_ext_stopwords">http://example.com/stopword.txt</entry>
</properties>

远程词典要求

  • HTTP 响应头包含 Last-ModifiedETag
  • 每次更新词典后,响应头需要变化
  • IK 分词器会定期检查更新

动态添加词汇

使用自定义分词过滤器

PUT /articles
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"type": "custom",
"tokenizer": "ik_max_word",
"filter": ["my_synonym"]
}
},
"filter": {
"my_synonym": {
"type": "synonym",
"synonyms": [
"ES,Elasticsearch",
"K8s,Kubernetes"
]
}
}
}
}
}

热更新词典

通过 API 动态添加词汇:

# 使用 _analyze 测试新词
GET /_analyze
{
"tokenizer": "ik_max_word",
"text": "新的词汇"
}

中文搜索最佳实践

最佳配置

PUT /articles
{
"settings": {
"analysis": {
"analyzer": {
"ik_index_analyzer": {
"type": "custom",
"tokenizer": "ik_max_word",
"filter": ["lowercase"]
},
"ik_search_analyzer": {
"type": "custom",
"tokenizer": "ik_smart",
"filter": ["lowercase"]
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_index_analyzer",
"search_analyzer": "ik_search_analyzer",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"content": {
"type": "text",
"analyzer": "ik_index_analyzer",
"search_analyzer": "ik_search_analyzer"
},
"tags": {
"type": "keyword"
}
}
}
}

高亮显示

GET /articles/_search
{
"query": {
"match": {
"content": "搜索技术"
}
},
"highlight": {
"pre_tags": ["<em>"],
"post_tags": ["</em>"],
"fields": {
"content": {
"fragment_size": 150,
"number_of_fragments": 3
}
}
}
}

拼音搜索

结合拼音插件实现拼音搜索:

# 安装拼音插件
bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v8.12.0/elasticsearch-analysis-pinyin-8.12.0.zip

# 配置拼音分词
PUT /articles
{
"settings": {
"analysis": {
"analyzer": {
"pinyin_analyzer": {
"tokenizer": "ik_max_word",
"filter": ["pinyin_filter"]
}
},
"filter": {
"pinyin_filter": {
"type": "pinyin",
"keep_full_pinyin": true,
"keep_original": true
}
}
}
}
}

小结

本章我们学习了:

  1. 中文分词的必要性
  2. IK 分词器的安装和使用
  3. ik_smart 和 ik_max_word 的区别
  4. 自定义词典配置
  5. 中文搜索最佳实践

练习

  1. 安装 IK 分词器并测试分词效果
  2. 创建一个使用 IK 分词器的文章索引
  3. 配置自定义词典添加专业术语
  4. 实现中文搜索并高亮显示

参考资源