1. ES 概述
1.1. elasticsearch 简介
ElasticSearch是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。
Elastic官方宣布Elasticsearch进入Version 8,在速度、扩展、高相关性和简单性方面开启了一个全新的时代。
说明:Elasticsearch 8最低jdk版本要求jdk17,当前我们选择Elasticsearch版本:Elasticsearch8.5.3
DB-Engines Ranking - popularity ranking of database management systems
1.2. Elasticsearch的特性
- 实时理论上数据从写入Elasticsearch到数据可以被搜索只需要1秒左右(p、n 级别数据)的时间,实现准实时的数据索引和查询。
- 高可用 数据多副本、多节点存储,单节点的故障不影响集群的使用,默认天生集群模式。
- Rest APIElasticsearch提供标准的Rest API,这使得所有支持Rest API的语言都能够轻易的使用Elasticsearch,具备多语言通用的支持特性,易于使用。Elasticsearch Version 8以后,去除了以前High-Level API、Low-Level API,统一标准的Rest API,这将使得Elasticsearch更加容易使用,原来被诟病的API混乱问题终于得到完美解决。
- 多客户端支持支持Java、Python、Go、PHP、Ruby等多语言客户端,还支持JDBC、ODBC等客户端。
1.3. Elasticsearch应用场景
- 作为独立数据库系统 Elasticsearch本身提供了数据持久化存储的能力,并且提供了增删改查的功能,在某些应用场景下可以直接当做数据库系统来使用,既提供了存储能力,又能够同时具备搜索能力,整体技术架构会比较简单,例如
博客系统、评论系统
。需要注意的是,Elasticsearch不支持事务,且写入的性能相对关系型数据库稍弱,所有需要使用事务的场景都不能将Elasticsearch当做唯一的数据库系统,这使得这种使用场景很少见。
可以混合使用MySQL + ES
。
- 搭建搜索系统(配合MySQL使用)Elasticsearch为搜索而生,用于搭建全文搜索系统是自然而然的事情,它能够提供快速的索引和搜索功能,还有相关的评分功能、分词插件等,支持丰富的搜索特性,可以用于搭建大型的搜索引擎,更加常用语实现站内搜索,例如银行App、购物App等站内商品、服务搜索。
- 目前大量的需要支持事务的系统使用
MySQL作为数据库
,但随着业务的开展,数据量会越来越大,而MySQL的性能会越来越差,虽然可以通过分库分表的方案进行解决,但是操作比较复杂,而且往往每隔一段时间就需要进行扩展,且代码需要配合修改。这种情况下可以将数据从MySQL同步到Elasticsearch,针对主要查询历史数据且数据量比较大的而且不需要事务控制等场景使用Elasticsearch提供查询,而对需要事务实时控制的即时数据还是通过MySQL存储和查询。 - 搭建日志系统日志系统应该是Elasticsearch使用最广泛的场景之一了,Elasticsearch支持海量数据的存储和查询,特别适合日志搜索场景。广泛使用的ELK套件(Elasticsearch、Logstash、Kibana)是日志系统最经典的案例,使用Logstash和Beats组件进行日志收集,Elasticsearch存储和查询应用日志,Kibana提供日志的可视化搜索界面。

- 搭建数据分析系统 (大数据领域)Elasitcsearch支持数据分析,例如强大的数据聚合功能,通过搭配Kibana,提供诸如
直方图、统计分组、范围聚合
等方便使用的功能,能够快速实现一些数据报表等功能。
1.4. 数据的分类:
1.4.1. 结构化数据:
特点:将数据具有的特征事先以结构化的形式定义好,数据有固定的格式或有限的长度。
典型的结构化数据就是传统关系型数据库的表结构,数据特征直接体现在表结构的字段上。
通过字段表示出来,就是结构化数据
1.4.2. 非结构化数据:
特点:数据没有预先定义好的结构化特征,也没有固定格式和固定长度。
典型的非结构化数据包括文章、图片、视频、邮件等。
1.5. 全文检索
概念:对于非结构化的数据检索,被称为全文检索。
背景:
假设现在MySQL中有一张User表,含有三个字段:姓名name、年龄age和爱好favor:
对于User表来说,整体上是结构化的。
比如name
、age
都可以直接建立索引来快速地检索。

而单个字段可以认为是非结构化的。其中的favor
字段是一个text类型,存储的是非结构化
的文本数据。(我喜欢java;篮球、足球、爱运动的我等)
与结构化查询相比,全文检索面临的最大问题就是性能问题。全文检索最一般的应用场景是根据一些关键字查找包含这些关键字的文档,比如互联网搜索引擎要实现的功能就是根据一些关键字查找网页。显然,如果没有对文档做特别处理,查找的办法似乎只能是逐条比对。比如:
假设现在需要找到favor中含有"足球"这个关键字的User,那么只能使用like模糊查询:
select * from user where favor like '%足球%'
而like语句是无法建立索引的,查询时会进行全表扫描,并且在每个favor字段中进行遍历匹配,以找到含有"足球"这个关键字的记录,整体复杂度特别高,所以对于全文检索来说关系型数据库不是能很好的支持。为了解决这个问题,需要一种新索引方法,这种索引方法就是倒排索引。
1.6. 倒排索引
1.6.1. 倒排索引原理:
倒排索引先将文档中包含的关键字全部提取出来,然后再将关键字与文档的对应关系保存起来,最后再对关键字本身做索引排序。用户在检索某一关键字时,可以先对关键字的索引进行查找,再通过关键字与文档的对应关系找到所在文档。
搜索条件:我用搜索引擎

分词会有两次,第一次建立索引分词,第二次是搜索时还继续分词。
1.6.2. 倒排索引的查询过程
-
用户输入 → "Elasticsearch OR Pydantic"
-
解析查询
{
"bool": {
"should": [
{"match": { "content": "Elasticsearch" }},
{"match": { "content": "Pydantic" }}
]
}
} -
词项分解 ["elasticsearch", "pydantic"]
-
倒排列表查找 [1], [2]
-
合并结果 [1, 2] (OR 操作)
-
[应用过滤器] 假设无过滤条件,保留全部文档
-
[计算评分] 为文档 1 和 2 分配得分
-
[排序] 按得分降序排列
-
[分页] 返回第 1 页(默认 size=10)
-
[返回结果] → {"*id":1, "content":"Elasticsearch..."}, {"*id":2, "content":"Pydantic..."}
1.6.3. 优点
- 高效的关键词搜索:倒排索引允许快速查找包含特定关键词的文档,极大提高了查询效率。
- 可扩展性:通过分片和副本机制,保证Elasticsearch能够处理大规模数据,保证高可扩展性和高可用性。
- 灵活的查询能力:支持多种查询类型,如布尔查询、范围查询、模糊查询等,满足不同应用需求。
1.6.4. 缺点
- 存储空间占用较大:倒排索引需要存储倒排列表,可能占用较多存储空间,尤其是处理大规模文本数据时。
- 准实时性较弱:由于倒排索引的构建和更新需要一定时间,可能无法满足高实时性要求的应用场景。
2. ES 安装
本身之前安装了ES docker
镜像。ES 版本为 8.5.0
现在安装 IK
分词器。IK
和 ES
的版本要完全一致。IK 官网 下载安装包
# docker 容器内执行
bin/elasticsearch-plugin install https://get.infini.cloud/elasticsearch/analysis-ik/8.5.0
# 查看是否安装成功
bin/elasticsearch-plugin list
analysis-ik
3. 核心概念
3.1. es对照数据库

3.2. 索引(Index)(逻辑概念)
一个索引就是一个拥有几分相似特征的文档的集合。
比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母),并且当我们要对这个索引中的文档进行分词索引查找、搜索、更新和删除的时候,都要使用到这个名字。
3.3. 类型(Type)(逻辑概念)
在一个索引中,你可以定义一种或多种类型。
一个类型是你的索引的一个逻辑上的分类/分区
,其语义完全由你来定。
通常,会为具有一组共同字段的文档定义一个类型。不同的版本,类型发生了不同的变化
|-----|---------------------------|
| 版本 | Type |
| 5.x | 支持多种type |
| 6.x | 只能有一种type |
| 7.x | 默认不再支持自定义索引类型(默认类型为:_doc) |
| 8.x | 默认类型为:_doc |
3.4. 文档(Document)
一个文档是一个可被找到的基础信息单元,也就是一条数据
比如:你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON(Javascript Object Notation)格式来表示,因为JSON是一个目前存在的互联网最方便的数据交互格式。
在一个index/type里面,你可以存储任意多的文档。
3.5. 字段(Field)
相当于是数据表的列,对文档数据根据不同属性进行的分类标识。
3.6. 映射(Mapping)
mapping
是处理数据的方式和规则方面做一些限制,如:某个字段的数据类型、默认值、分词器、是否建立倒排索引等等。这些都是映射里面可以设置的,其实就是处理ES里面数据的一些使用规则设置。
分词会有两次,第一次建立索引分词,第二次是搜索时还继续分词。
index:true
代表要不要建立倒排索引,要注意:倒排索引和分词没有必然联系,不分词也可以简历倒排索引
分词就是能不能拆开:所以看属性能不能分词,比如分类为红米,比如标题为红米手机
可以理解为模糊查询为分词,不分词就是精准查询