引言

上一篇我们踩完了 ES 安装的所有坑,成功跑通了第一个搜索服务。很多同学可能会好奇:ES 到底是怎么做到毫秒级搜索的?为什么同样是查数据,它比 MySQL 快这么多?

答案就是 ES 的灵魂 ——倒排索引。今天我就用 “查字典” 这个大家都懂的例子,把倒排索引讲透,再带大家实战 IK 分词器和字段映射,保证看完不仅能懂,还能直接用到项目里!

一、ES 的灵魂:倒排索引到底是什么?

先问大家一个问题:你查字典的时候,是从第一页开始翻,直到找到你要的字吗?

当然不是!我们都是先查目录(拼音或部首),找到这个字对应的页码,再直接翻到那一页。

这就是倒排索引的核心思想!我们来对比一下:

  • 正排索引:文档 → 关键字(从第一页翻字典,先拿到文档,再找里面的关键字)

  • 倒排索引:关键字 → 文档(先查目录找到关键字,再找到包含这个关键字的所有文档)

举个实际的例子

假设我们有两篇文档:

  • 文档 1:Python从入门到放弃

  • 文档 2:Java从入门到精通

ES 会先对这两篇文档进行分词,得到下面的倒排索引表:

关键字(Term)

包含该关键字的文档 ID

Python

1

Java

2

入门

1, 2

放弃

1

精通

2

当用户搜索 “入门” 时,ES 直接去倒排索引表里找 “入门” 这个关键字,瞬间就能知道文档 1 和文档 2 都包含它,然后返回结果。

而如果用 MySQL 的like '%入门%',它会把所有文档都读一遍,逐个检查是否包含 “入门” 两个字,速度自然天差地别。

倒排索引的小细节

  1. 分词列表(Term)是不重复的,比如 “入门” 只会出现一次

  2. 停用词(的、地、得、a、an、the)不会被加入分词列表,因为它们没有实际搜索意义

  3. 不需要搜索的字段(比如图片 URL)不会参与分词,节省空间

二、中文分词神器:IK 分词器的安装与自定义

ES 默认的分词器对中文很不友好,它会把 “我爱中国” 分成 “我”、“爱”、“中”、“国” 四个单字,完全不符合我们的搜索习惯。

这时候就需要用到IK 分词器,它是目前最流行的中文分词器,支持两种分词模式:

  • ik_smart:粗粒度分词,适合搜索时使用(比如 “清华大学” 会分成 “清华大学”)

  • ik_max_word:细粒度分词,适合写入数据时使用(比如 “清华大学” 会分成 “清华大学”、“清华”、“大学”)

1. 安装 IK 分词器

超级简单,只要把 IK 分词器的压缩包解压到 ES 的plugins目录下,并重命名为ik即可:


2. 自定义词典

IK 分词器虽然强大,但还是会有一些网络热词或者专业术语识别不出来,比如 “奥里给”、“ES 入门”。这时候我们可以自定义词典:

  1. 编辑/usr/local/elasticsearch-6.2.3/plugins/ik/config/IKAnalyzer.cfg.xml


  1. main.dic里添加你想要的新词,每行一个:


  1. stopword.dic里添加你想要过滤的停用词:


✅ 注意:词典文件必须保存为UTF-8 编码,否则会乱码!修改完重启 ES 生效。

三、字段(Field)详解:写对映射,搜索效率翻倍

ES 的字段(Field)相当于 MySQL 的列,字段类型和属性的设置直接影响搜索的效率和准确性。

1. 常用字段类型

类型

说明

text

会被分词,适合存储长文本(比如课程描述、文章内容)

keyword

不会被分词,适合存储精确值(比如手机号、邮箱、分类 ID)

integer

整数类型

long

长整数类型

float

单精度浮点数

double

双精度浮点数

2. 核心字段属性

  • type:字段的数据类型,这是最基础的属性

  • analyzer:写入数据时使用的分词器,一般设为ik_max_word

  • search_analyzer:搜索时使用的分词器,一般设为ik_smart

  • index:是否为该字段建立倒排索引,不需要搜索的字段设为false,节省空间

  • _source:是否存储该字段的原始值,不需要展示的字段可以排除

3. 字段属性设置标准(记住这三条就够了)

  1. type:看分词是否有意义。比如 “课程名” 分词有意义,用text;“课程 ID” 分词没意义,用keyword

  2. index:看是否需要搜索。比如 “图片 URL” 不需要搜索,设为false

  3. _source:看是否需要展示。比如一些内部字段不需要返回给前端,可以排除

实战:创建一个合理的 Type 映射

发送 POST 请求到 http://192.168.61.135:9200/java06/_course/_mapping


四、ES 客户端与 Spring Boot 整合

最后说一下 Java 项目中怎么使用 ES。ES 提供了两种客户端:

  • TransportClient:基于 TCP 协议,ES 8.0 后会被删除,不推荐使用

  • RESTHighLevelClient:基于 HTTP 协议,官方推荐使用

在 Spring Boot 项目中,我们可以直接使用启动器:


然后在配置文件中指定 ES 的地址,就可以通过ElasticsearchRestTemplate来操作 ES 了,非常方便。

五、面试高频考点总结

  1. ES 为什么比 MySQL 快?核心是倒排索引

  2. 正排索引和倒排索引的区别?

  3. IK 分词器的两种模式及使用场景?

  4. 主分片数量为什么创建后不能修改?

  5. text 和 keyword 的区别?

六、写在最后

ES 作为现在最流行的全文检索引擎,已经成为 Java 后端开发的必备技能。很多同学觉得 ES 难,其实是被它的概念吓到了 —— 只要搞懂了倒排索引这个核心,其他的都是水到渠成。

下一篇我会带大家做一个完整的课程搜索功能,从前端输入关键词到后端 ES 查询,一步步实现一个生产级别的搜索接口,敬请期待!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐