文章目錄
- Elasticsearch簡介
- ES概念
- ES和關系型數據庫的對比
- 正序索引和倒序索引
- 安裝es、kibana、IK分詞器
- ES操作
- _cat操作
- Mapping映射屬性
- 索引庫操作
- 索引庫CRUD
- 文檔CRUD
- 文檔批處理操作
- Java客戶端操作ES
Elasticsearch簡介
就是一個搜索引擎數據庫
以下都簡稱ES
ES概念
ES和關系型數據庫的對比
ES是面向文檔的!文檔數據都會序列化為JSON格式存儲,所以一切都是Json ,ES(集群)中可以包含多個索引(數據庫),每個索引中可以包含多個類型(表)(類型es8后被棄用,一個索引下存儲單一類型數據),每個類型/索引下又包含多個文檔(行),每個文檔中又包含多個字段(列)
SQL是操作SQL數據庫的語法,DSL是操作ES數據庫的語法
概念/功能 | Elasticsearch (ES) | MySQL | 核心差異說明 |
---|---|---|---|
數據組織層級 | |||
索引 | Index(最高層級邏輯數據容器) | Database | ES的Index類似于MySQL的Database,都是頂層數據容器 |
類型 | 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 可以防止檢索錯誤
每一個字段都有上面對應的屬性
比如下面這個
{
"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請求
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"}}}}}
}
查詢索引庫
GET /xiaoyuan
xiaoyuan為索引庫名
刪除索引庫
DELETE /xiaoyaun
xiaoyuan為索引庫名
ES索引庫不支持修改,不可以對已有數據段修改,但是可以添加新字段
如圖
文檔CRUD
新增文檔
POST /索引庫/_doc/文檔ID(不寫自動生成)
{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"
}
讀取文檔
GET /products/_doc/文檔ID
獲取單個文檔
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"}}
}
刪除文檔
DELETE /索引庫名/_doc/文檔ID
# 刪除單個文檔
DELETE /products/_doc/1# 響應示例
{"_index": "products","_id": "1","_version": 2,"result": "deleted"
}# 按查詢刪除(刪除所有庫存為0的商品)
POST /products/_delete_by_query
{"query": {"term": {"stock": 0}}
}
更新文檔(分兩種)
1.全量修改
2.增量修改
全量修改
相當于是先刪除原文檔再添加新文檔
語法
PUT /索引庫名/_doc/文檔ID
{ 數據 }
實例
替換整個文檔(覆蓋操作)
PUT /products/_doc/1
{"name": "Premium Headphones","price": 149.99,"description": "Deluxe noise-cancelling model","stock": 40,"created_at": "2023-10-25T08:30:00Z"
}
增量修改
語法
POST /索引庫名/_update/文檔id
{
"doc" {"字段名":"新的值",...}
}
實例
部分更新(增加庫存)
POST /products/_update/1
{"doc": {"stock": 60}
}
文檔批處理操作
一次請求包含多個文檔操作
解釋如下
POST /_bulk 作為請求路徑
"index"索引,動詞索引就是插入數據唄(或者全量改動)
索引一個文檔,后面接著一條數據,需要指定_index-索引庫和_Id文檔id(不寫默認生成)
"index"和"create"相似,但是"create"是只可以創建,不能覆蓋
而"index"既可以創建新的,也可以覆蓋原來的文檔
"update"是增量改動,跟著一行"doc"攜帶修改字段
"delete"刪除指定索引庫和文檔ID即可
案例
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了