文章目录
Elasticsearch简介
就是一个搜索引擎数据库
以下都简称ES
ES概念
ES和关系型数据库的对比
ES是面向文档的!文档数据都会序列化为JSON格式存储,所以一切都是Json ,ES(集群)中可以包含多个索引 (数据库),每个索引中可以包含多个类型 (表)(类型es8后被弃用,一个索引下存储单一类型数据 ),每个类型/索引下又包含多个文档 (行),每个文档中又包含多个字段 (列)
SQL是操作SQL数据库的语法,DSL是操作ES数据库的语法
概念/功能 | Elasticsearch (ES) | MySQL | 核心差异说明 |
---|---|---|---|
数据组织层级 | |||
索引 | Index(最高层级逻辑数据容器) | Database | ES的Index类似于MySQL的Database,都是顶层数据容器 |
类型 | Type(已废弃) | Table | ES的类型概念已淘汰,现在每个索引存储单一类型数据 |
文档 | Document(JSON格式基本数据单元) | Row | 文档是半结构化JSON,行是结构化记录 |
字段 | Field(JSON键值对) | Column | ES字段动态灵活,MySQL列需预定义 |
数据定义 | |||
结构定义 | Mapping(定义字段类型和属性) | Schema | ES映射支持动态添加字段,MySQL需预定义结构 |
唯一标识 | _id (文档唯一标识) |
Primary Key | 功能相似,都是数据唯一标识符 |
数据操作 | |||
查询语言 | Query DSL(JSON格式) SQL Over ES(有限支持) | SQL | ES主要使用专用JSON查询,MySQL使用标准SQL |
写入/更新 | Index API(写入) Update API(部分更新) | INSERT/UPDATE/DELETE | ES写入称为"索引",支持脚本更新 |
系统特性 | |||
事务支持 | ❌ 不支持ACID事务 | ✅ 支持ACID事务 | MySQL适合银行交易等场景,ES不适合 |
数据一致性 | ⏱️ 最终一致性(近实时NRT) | ✅ 强一致性 | ES写入后约1秒可查,MySQL立即可见 |
存储引擎 | Apache Lucene(倒排索引+Doc Values) | InnoDB(B+树索引) | Lucene优化全文搜索,InnoDB优化事务处理 |
索引机制 | 🔄 自动索引所有字段 倒排索引(文本) Doc Values(聚合) | ⚙️ 需显式创建索引 B+树索引(主键/普通) FULLTEXT(全文) | ES默认索引所有字段,MySQL需手动创建 |
扩展性 | ⚡ 原生分布式 自动分片(Shard) 副本(Replica) | 🧩 需分库分表 主从复制 | ES天生分布式易扩展,MySQL水平扩展复杂 |
主要用途 | 🔍 全文搜索 📊 日志/指标分析 🌐 地理空间分析 | 💳 事务处理(OLTP) 🧾 关系数据管理 📈 报表查询(OLAP) | ES擅长搜索分析非结构化数据,MySQL擅长事务管理结构化数据 |
最佳实践 | |||
适用场景 | 搜索引擎、日志分析、实时监控 | 电商交易、用户管理、财务系统 | 常组合使用:MySQL作主数据源,ES提供搜索分析 |
数据模型 | 无模式(Schema-less) JSON文档 | 严格模式(Schema-on-Write) 行列结构 | ES灵活适合变化数据,MySQL严谨保证数据完整性 |
两者的不同 | |||
![]() |
正序索引和倒序索引
正序索引就是关系型数据库用的,但是这种使用%小米%这种模糊搜索的时候会导致正向索引失效,然后一个一个去比对,会非常浪费时间(当数据量非常大的时候)
倒序索引就是你在插入文档的时候,将拿到词分成几个词条(比如小米手机会分成小米和手机),并且记录相应的文档id,之后分词还有相同的会记录到一个词条中
然后我们搜索的时候,比如搜索华为手机
安装es、kibana、IK分词器
es是数据库,kibana可以理解为navicat是看es中数据的
这里不做讲解哈
可以看一下其他的文章
ES操作
对于ES的所有操作ES都封装成立restfulapi用http请求调用
和我们的mysql需要用connection一样
_cat操作
直接
http://`es所在IP`:es启动端口号
/_cat/master
Mapping映射属性
其实还有一个type类型为:nested 可以防止检索错误
每一个字段都有上面对应的属性
比如下面这个
json
{
"age": 21,
"weight": 52.1,
"isMarried":false,
"info":"黑马程序员Java讲师",
"email":"zy@itcast.cn",
"score":[99.1,99.5,98.9],
"name":
{"firstName":"云",
"lastName":"赵"}
}
age字段type对应数值呗,byte就够用,index有无看需求(是否参与搜索或者排序),21肯定是不需要分词器的,无子字段所以肯定没有properties
info字段对应text,因为可以分词,index肯定是要的,分词器需要自己指定,无子字段
name是有子字段的(嵌套object对象),所有有properties,里面每一个值又单独有自己的mapping
firstname肯定还是keyword不需要分词
这个score的type是float ,es中,所有数组类型我们都不用管,只需要看里面元素的类型
索引库操作
ES都是基于Restful的接口,先介绍一下Restful
索引库CRUD
下面对应索引库的文档的CRUD操作我都将在kibana的开发工具中发送http请求(有提示),且不用带上我们的es ip+端口,因为kibana是和es本身就绑定的
如图
创建索引命令
里面设置对应的mapping
新增索引库 注:这里新增是PUT请求
json
PUT /heima
{
"mappings": {
"properties": {
"info":{
"type": "text",
"analyzer": "standard",
"index": true
},
"age":{
"type": "byte",
"index": true
},
"email":{
"type": "keyword",
"index": false
},
"name":{
"type": "object",
"properties": {
"firstName":{
"type": "keyword"
},
"lastName":{
"type": "keyword"
}
}
}
}
}
}
查询索引库
java
GET /xiaoyuan
xiaoyuan为索引库名
删除索引库
java
DELETE /xiaoyaun
xiaoyuan为索引库名
ES索引库不支持修改,不可以对已有数据段修改,但是可以添加新字段
如图
文档CRUD
新增文档
java
POST /索引库/_doc/文档ID(不写自动生成)
{json数据-应对应索引库结构}
json
添加文档(指定ID) 1为指定的ID
POST /products/_doc/1
{
"name": "Wireless Headphones",
"price": 129.99,
"description": "Noise-cancelling Bluetooth headphones",
"stock": 50,
"created_at": "2023-10-25T08:30:00Z"
}
添加文档(自动生成ID)
POST /products/_doc
{
"name": "Smart Watch",
"price": 299.99,
"description": "Water-resistant fitness tracker",
"stock": 25,
"created_at": "2023-10-26T10:15:00Z"
}
响应示例(自动ID)
{
"_index": "products",
"_id": "abc123xyz",(返回的文档id)
"_version": 1,
"result": "created"
}
读取文档
java
GET /products/_doc/文档ID
json
获取单个文档
GET /products/_doc/1
响应示例
{
"_index": "products",
"_id": "1",
"_version": 1,
"_source": {
"name": "Wireless Headphones",
"price": 129.99,
"description": "Noise-cancelling Bluetooth headphones",
"stock": 50,
"created_at": "2023-10-25T08:30:00Z"
}
}
搜索文档
GET /products/_search
{
"query": {
"match": {
"description": "bluetooth"
}
}
}
删除文档
java
DELETE /索引库名/_doc/文档ID
json
# 删除单个文档
DELETE /products/_doc/1
# 响应示例
{
"_index": "products",
"_id": "1",
"_version": 2,
"result": "deleted"
}
# 按查询删除(删除所有库存为0的商品)
POST /products/_delete_by_query
{
"query": {
"term": {
"stock": 0
}
}
}
更新文档(分两种)
1.全量修改
2.增量修改
全量修改
相当于是先删除原文档再添加新文档
语法
java
PUT /索引库名/_doc/文档ID
{ 数据 }
实例
json
替换整个文档(覆盖操作)
PUT /products/_doc/1
{
"name": "Premium Headphones",
"price": 149.99,
"description": "Deluxe noise-cancelling model",
"stock": 40,
"created_at": "2023-10-25T08:30:00Z"
}
增量修改
语法
json
POST /索引库名/_update/文档id
{
"doc"
{"字段名":"新的值",
...}
}
实例
json
部分更新(增加库存)
POST /products/_update/1
{
"doc": {
"stock": 60
}
}
文档批处理操作
一次请求包含多个文档操作
解释如下
java
POST /_bulk 作为请求路径
"index"索引,动词索引就是插入数据呗(或者全量改动)
索引一个文档,后面接着一条数据,需要指定_index-索引库和_Id文档id(不写默认生成)
"index"和"create"相似,但是"create"是只可以创建,不能覆盖
而"index"既可以创建新的,也可以覆盖原来的文档
"update"是增量改动,跟着一行"doc"携带修改字段
"delete"删除指定索引库和文档ID即可
案例
json
POST /_bulk
{ "index" : { "_index" : "products", "_id" : "101" } }
{ "name": "USB-C Cable", "price": 15.99, "stock": 200 }
{ "create" : { "_index" : "products", "_id" : "102" } }
{ "name": "Phone Charger", "price": 29.99, "stock": 150 }
{ "update" : {"_id" : "101", "_index" : "products"} }
{ "doc" : {"stock": 180} }
{ "delete" : { "_index" : "products", "_id" : "100" } }
Java客户端操作ES
对应的可以操作ES的API有很多种(其实可以发http请求的的可以操作不过要自己封装很麻烦)
我们用Elasticsearch-Rest-Client这个官方提供的
比如我们操作redis就用Spring Data Redis这个依赖一样的(或者redisson)
这里的话暂时不做讲解,因为gulimall对应的操作api好像已经过期了,es8后又需要其他api了