Elasticsearch IK 分词器自定义词典——扩展词、停用词、热更新、同义词

IK 分词器默认的词库是通用的,但每个项目都有自己的专有名词------小红书里"显眼包""多巴胺穿搭",电商里"充氮气独立包装"------这些词 IK 默认会把它们切成一堆碎词,搜索体验很差。这篇文章覆盖 IK 分词器的四种自定义配置:扩展词词典(让 IK 认识你的专有名词)、停用词词典(过滤掉无意义的词)、MySQL 热更新词典(改词库不用重启 ES)、同义词词典(搜"笔记本"也召回"笔记本电脑")。


为什么默认词库不够用

复制代码
默认分词:多巴胺穿搭 → ["多巴胺", "穿搭"]   ← 能分出来
         显眼包    → ["显", "眼", "包"]     ← 拆碎了,搜"显眼包"召回不准
         充氮气独立包装 → ["充", "氮气", "独立", "包装"]  ← "充氮气"应该是一个词

专有名词被拆碎了之后,倒排索引里没有完整的 term,搜"显眼包"召回不到。需要让 IK 知道"'显眼包'是一个完整的词,别拆"。


找到 IK 配置目录

Docker 部署的 ES,IK 配置路径在:

复制代码
/usr/share/elasticsearch/plugins/ik/config/
├── IKAnalyzer.cfg.xml      ← 主配置文件,所有词典入口
├── main.dic                ← IK 自带扩展词库
├── stopword.dic            ← IK 自带停用词库
└── ...(拼音、繁体等可选模块)

建议把目录挂出来方便改:

bash 复制代码
docker run -d \
  --name es \
  -p 9200:9200 \
  -v ./es-plugins/ik:/usr/share/elasticsearch/plugins/ik \
  elasticsearch:8.15.0

改完重启容器生效。下面所有的 .dic 文件都放在这个 config/ 目录下,和 IKAnalyzer.cfg.xml 同级。


完整配置一览

先把 IKAnalyzer.cfg.xml 的最终形态放这里------四种词典的入口都在这一处。后面每个小节分别讲对应文件怎么写。

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <comment>IK Analyzer 扩展配置</comment>

    <!-- 扩展词词典:本地文件,改完重启 ES -->
    <entry key="ext_dict">my_ext.dic</entry>

    <!-- 停用词词典:本地文件,改完重启 ES -->
    <entry key="ext_stopwords">my_stop.dic</entry>

    <!-- 扩展词热更新:MySQL,不重启 -->
    <entry key="remote_ext_dict">jdbc:mysql://host.docker.internal:3306/ik?useSSL=false&amp;serverTimezone=Asia/Shanghai</entry>
    <entry key="remote_ext_dict_table">ik_ext_dict</entry>
    <entry key="remote_ext_dict_column">word</entry>

    <!-- 停用词热更新:MySQL,不重启 -->
    <entry key="remote_ext_stopwords">jdbc:mysql://host.docker.internal:3306/ik?useSSL=false&amp;serverTimezone=Asia/Shanghai</entry>
    <entry key="remote_ext_stopwords_table">ik_stop_dict</entry>
    <entry key="remote_ext_stopwords_column">word</entry>

    <!-- 统一刷新间隔(秒) -->
    <entry key="remote_ext_dict_interval">60</entry>
</properties>
entry 干什么 更新方式
ext_dict 扩展词(专有名词) .dic 文件 → 重启 ES
ext_stopwords 停用词(无意义词) .dic 文件 → 重启 ES
remote_ext_dict 扩展词热更新 改 MySQL → 等 60s 自动生效
remote_ext_stopwords 停用词热更新 改 MySQL → 等 60s 自动生效
remote_ext_dict_interval 刷新间隔 默认 60 秒

1 扩展词词典------让 IK 认识你的专有名词

config/ 下新建 my_ext.dic,一行一个词:

复制代码
# my_ext.dic
显眼包
多巴胺穿搭
充氮气
程一口
独立包装

重启 ES 后验证:

bash 复制代码
curl -X POST "http://localhost:9200/_analyze" \
  -H 'Content-Type: application/json' \
  -d '{ "analyzer": "ik_max_word", "text": "充氮气独立包装" }'

# 返回:["充氮气", "独立", "包装"]
# "充氮气" 被保留成完整词了 ✅

2 停用词词典------过滤掉无意义的词

config/ 下新建 my_stop.dic

复制代码
# my_stop.dic
的
了
是
在
和
也
就
都
吗
呢
吧

重启 ES 后验证:

bash 复制代码
curl -X POST "http://localhost:9200/_analyze" \
  -H 'Content-Type: application/json' \
  -d '{ "analyzer": "ik_max_word", "text": "今天天气太热了" }'

# "了" 被过滤掉了 ✅

3 MySQL 热更新------改词库不用重启 ES

重启一次几分钟,词库经常变的话吃不消。IK 1.10.0+ 支持 MySQL 热更新:启动时加载,之后每隔 60 秒去查一次,有新词自动加载到内存。

建表

sql 复制代码
CREATE DATABASE ik;
USE ik;

-- 扩展词表
CREATE TABLE ik_ext_dict (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    word VARCHAR(255) NOT NULL COMMENT '扩展词',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO ik_ext_dict(word) VALUES ('显眼包'), ('多巴胺穿搭'), ('程一口');

-- 停用词表
CREATE TABLE ik_stop_dict (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    word VARCHAR(255) NOT NULL COMMENT '停用词',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO ik_stop_dict(word) VALUES ('的'), ('了'), ('呢'), ('吧');

放 MySQL 驱动

bash 复制代码
# 下载 mysql-connector-j,放到 plugins/ik/ 目录下(和 IK 的 jar 同级)
cp mysql-connector-j-9.2.0.jar ./es-plugins/ik/

配置项说明

配置 含义
remote_ext_dict JDBC 连接串(用户名密码用 &user=root&password=xxx 拼在 URL 里)
remote_ext_dict_table 扩展词表名
remote_ext_dict_column 扩展词所在的列名
remote_ext_stopwords 停用词 JDBC 连接串
remote_ext_stopwords_table 停用词表名
remote_ext_stopwords_column 停用词所在的列名
remote_ext_dict_interval 刷新间隔(秒)

用户名密码写 JDBC URL 里:jdbc:mysql://host:3306/ik?user=root&password=123456&useSSL=false

重启 ES 后,往 MySQL INSERT 一条新词,等 60 秒,验证:

bash 复制代码
INSERT INTO ik_ext_dict(word) VALUES ('新测试词');

# 等 60 秒后
curl -X POST "http://localhost:9200/_analyze" \
  -H 'Content-Type: application/json' \
  -d '{ "analyzer": "ik_max_word", "text": "新测试词在这里" }'

# "新测试词" 被完整保留 → 热更新生效 ✅

4 同义词词典------搜"笔记本"也召回"笔记本电脑"

同义词不归 IK 管,属于 ES 的 synonym token filter。

新建同义词文件

synonyms.txt 放在 ES 的 config/ 目录下(/usr/share/elasticsearch/config/,不是 IK 的 config),一行一组:

复制代码
笔记本, 笔记本电脑, laptop
显眼包, 显眼, 显眼精
充氮气, 氮气填充

创建 Index 时配上同义词 filter

json 复制代码
PUT /articles
{
  "settings": {
    "analysis": {
      "filter": {
        "my_synonym_filter": {
          "type": "synonym",
          "synonyms_path": "analysis/synonyms.txt"
        }
      },
      "analyzer": {
        "ik_synonym_smart": {
          "tokenizer": "ik_smart",
          "filter": ["my_synonym_filter"]
        },
        "ik_synonym_max_word": {
		      "type": "custom",
		      "tokenizer": "ik_max_word",
		      "filter": ["my_synonym_filter"]
		    }
      }
    }
  },
  "mappings": {
    "properties": {
      "content": {
        "type": "text",
        "analyzer": "ik_synonym"
      }
    }
  }
}

搜"笔记本"时,ES 自动把"笔记本电脑"也加入查询,多种说法都能召回。

同义词文件更新后,新写入的数据立即生效,已有数据需要 reindex 重建索引

相关推荐
广州浮点FLOATLIC1 小时前
Mentor Graphics浮动许可证管理为什么一到流片节点就失控
java·大数据·数据库·许可证管理·cad 许可证优化
Elasticsearch1 小时前
ES 存日志很贵?我用 ES 9.5 把日志从 4.5G 压到 412M 压缩比11.2倍,日志硬扫每秒128万行!
elasticsearch
ha_lydms1 小时前
使用SQL导入MaxCompute的数据至Hologres
大数据·sql·dataworks·maxcompute·hologres·odps·datastudio
2601_949499942 小时前
硬件工程师实操:芯瑞科技两款 400G 高速互联方案参数、场景、选型全解析
大数据·运维·人工智能·科技·光模块
优氙费控2 小时前
报销审核效率低?AI费用审核正在改变财务工作方式
大数据·人工智能
云边云科技_云网融合2 小时前
金融医疗混合云组网如何满足数据安全与合规要求?
大数据·人工智能·物联网
hzcj8882 小时前
汇正财经:出海数据向好,创新药热度高
大数据·人工智能
Bzc11456233 小时前
中医辨证调护:慢病视角下的血糖健康养护思路
大数据·人工智能·生活
Fluxart.ai3 小时前
2026电商AI出图质量验收标准与质检SOP完整教程
大数据·人工智能
泛普软件3 小时前
工程施工项目管理办公系统能解决哪些现场管理难题与超支问题
大数据·人工智能·软件需求