學習背景
由于最近作業需要,需要大量使用elasticsearch代替mysql資料庫進行資料存盤和查詢操作,但是目前關于相關的學習檔案較少,官方檔案看著也較為費勁,所以記錄一下我的學習記錄,
介紹
Elasticsearch是一個基于Lucene的搜索服務器,它提供了一個分布式的全文搜索引擎,基于restful web介面,Elasticsearch是用Java語言開發的,基于Apache協議的開源專案,是目前最受歡迎的企業搜索引擎,Elasticsearch廣泛運用于云計算中,能夠達到實時搜索,具有穩定,可靠,快速的特點,
關于Elasticsearch和可視化專案kibana的安裝這里就不多做介紹,需要的可以自行百度檢索安裝,
與Mysql資料庫的對應關系
| Elasticsearch | Mysql |
|---|---|
| 索引(index) | 資料庫(databases) |
| 型別(type) | 表(table) |
| 檔案(document) | 行(row) |
在Elasticsearch 7.X以后,官方將過度性移除型別(type),在8.X以后將完成移除type,此時Elasticsearch 資料結構將為兩層結構:索引和檔案,
Elasticsearch基本操作
- 在學習Elasticsearch基本操作命令之前需要了解restful風格介面在其應用中的規范
| 請求型別 | 作用 | 差異 |
|---|---|---|
| GET | 查詢操作 | 無 |
| PUT | 添加和修改操作 | 在進行添加操作時必須指定檔案id,否則報錯 |
| POST | 基本的查詢操作 | 在添加時可以不指定檔案id,系統會隨機為其生成一個檔案id |
| DELETE | 洗掉操作 | 無 |
1. 增刪改操作
1.1 增加操作(POST、PUT)
將name=小明,age=12資料插入到索引為test,型別為dd中保存
- 使用POST添加并且不帶檔案id
POST test/dd/
{
"name" : "小明",
"age" : 12
}
回傳的結果:
{
"_index" : "test",
"_type" : "dd",
"_id" : "z3EduXoBtsMqPf0VWJNp",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
其結果中的result欄位代表了該操作的狀態和型別,"created"表示新添加的并且成功了,并且該資料所在的索引、型別和檔案id都進行了顯示,當POST沒有指定檔案id時,系統會自動創建一個隨機id,
- 使用POST添加并且帶檔案id
POST test/dd/1
{
"name" : "小強",
"age" : 13
}
其結果為:
{
"_index" : "test",
"_type" : "dd",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
可以看出當帶上檔案id時,其就使用用戶指定的id,
- 使用PUT添加
PUT test/dd/2
{
"name" : "小文",
"age" : 14
}
其結果和前面一樣,這里就不再贅述,
當使用PUT進行添加操作時,如果不指定檔案id時,將會報錯,如下所示:
{
"error" : "Incorrect HTTP method for uri [/test/dd/?pretty=true] and method [PUT], allowed: [POST]",
"status" : 405
}
1.2 修改操作(POST、PUT)
修改操作和新增操作一樣,主要區別是,修改的前提必須在需要修改的索引-型別-檔案id下已經存在資料,并且其回傳結果的表示為:updated
1.3 洗掉操作(DELETE)
洗掉資料的陳述句可分為兩類:
1、DELETE 索引 //洗掉整個所有下的全部資料,相當于mysql的drop database 資料庫名
2、DELETE 索引/型別/檔案id //洗掉某個檔案id下的資料,相當于mysql的delete操作(洗掉一行)
Elasticsearch不支持洗掉型別操作,需要洗掉型別的話,就把該型別下的所有資料洗掉即可,
2. 查詢操作
- 為了更好的進行后續操作,本文將匯入官方提供的測驗資料,執行下面陳述句完成匯入
/**
*_bulk為elasticsearch的批量插入操作關鍵字,在索引為info,型別為account下插入資料
*/
POST /info/account/_bulk
復制測驗檔案里的所有內容
- 測驗資料檔案地址:鏈接:https://pan.baidu.com/s/1SW1hC9io1iEt1aSwYcvAPA 提取碼:1234
2.1 簡單查詢
- 全索引查詢
GET /bank/_search
其結果如下所示:由于資料太多,這里只展示第一條資料,后續資料省略,
{
"took" : 339,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1000,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "info",
"_type" : "account",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"account_number" : 1,
"balance" : 39225,
"firstname" : "Amber",
"lastname" : "Duke",
"age" : 32,
"gender" : "M",
"address" : "880 Holmes Lane",
"employer" : "Pyrami",
"email" : "amberduke@pyrami.com",
"city" : "Brogan",
"state" : "IL"
}
},
......
我們從hits內的hits可以查看到資料對應的鍵值對,下面將通過這些鍵值對完成復雜操作的查詢,
- 指定檔案id查詢
- 假如我們想查詢第一條資料,則可以通過制定檔案id完成制定資料查詢
GET /info/account/1
2.2 DSL陳述句查詢
- elasticsearch查詢模板
GET /索引名/_search //帶前綴 "_" 的都是elasticsearch自帶的關鍵字
{
"query": {
"想要查詢的型別":{
}
}
}
- 全資料查詢(match_all)
GET /info/_search
{
"query": {
"match_all": {}
}
}
- 指定欄位查詢
1、通過match關鍵字查詢
GET /info/_search
{
"query": {
"match": {
"FIELD": "TEXT"
}
}
}
2、通過term關鍵字查詢
GET /info/_search
{
"query": {
"term": {
"FIELD": "TEXT"
}
}
}
3、通過match_phrase關鍵字查詢
GET /info/_search
{
"query": {
"match_phrase": {
"FIELD": "TEXT"
}
}
}
上面三種關鍵字都可以對指定欄位進行查詢,其主要區別如下表所示:
| 關鍵字 | 特點 | 案例(查詢"雷神") |
|---|---|---|
| match | 模糊查詢(text型別),會對待欄位進行分詞操作,只要包含該欄位和其分詞后的字都可以查詢到, | ,只要包含"雷",“神”, "雷神"這些關鍵字的欄位都會被查詢到 |
| term | 精準查詢,將待查詢的欄位視為keyword型別,不會對其進行分詞操作 | 只能查詢到包含"雷神"的欄位 |
| match_phrase | 精準查詢,會進行分詞操作,與match主要不同的是,其會查詢包含所有分詞后的陳述句并且其順序要和原有順序一致,相當于一種段落精準查詢, | 進行分詞為"雷",“神”, “雷神”,可以查詢到順序和分詞順序一致的結果 |
- bool查詢
bool型別共包含四種查詢型別:must、must_not、should、filter,
GET /info/_search
{
"query": {
"bool": {
"must": [ //必須包含
{
"match": {
"FIELD": "TEXT"
}
}
],
"must_not": [ //一定不包含
{
"match": {
"FIELD": "TEXT"
}
}
],
"should": [ //可以包含,相當于or
{
"match": {
"FIELD": "TEXT"
}
}
],
"filter": [ //指定欄位進行查詢
{
"term": {
"FIELD": "VALUE"
}
}
]
}
}
}
從上面可以看出,關鍵字filter的和query的功能相似,但是其由一定的差異,如下表
| 關鍵字 | 特點 |
|---|---|
| query | 進行基本的查詢操作,同時對查詢的結果貢獻相關性得分,從而使結果進行排序 |
| filter | 只有查詢操作,其查詢的結果不會貢獻相關性得分 |
- 范圍查詢
如果我們想想Mysql一樣使用">“或者”<"符合來查詢范圍區間時,在elasticsearch中可以使用關鍵字"range"來完成,具體格式如下,該關鍵字和match等關鍵字一樣,可以使用在同樣位置,
"range": {
"age": {
"gt(e)": value1, //大于(等于)value1
"lt(e)": value2 //小于(等于)value2
}
}
-
聚合查詢
- 聚合查詢其含義與Mysql的聚合函式相似,可以為我們提高對資料的分析操作,其關鍵字為"aggs"
其格式如下所示:
- 聚合查詢其含義與Mysql的聚合函式相似,可以為我們提高對資料的分析操作,其關鍵字為"aggs"
"aggs": { //聚合查詢關鍵之,用來宣告一個聚合查詢段落
"name": { //自己定義的聚合查詢的名稱
"AGG_TYPE": { //聚合的型別
"field": field, //指定需要聚合操作的欄位名稱
}
}
}
elasticsearch提供了較多的聚合型別,常見的型別分為如下關鍵字:terms、sum、max、min、avg等,其中后四種用法相同,如上模板所示,其功能主要對指定的欄位進行相應的求和、求最大值、最小值、均值等,但是對于terms關鍵字用法有些區別,具體如下:
"aggs": {
"aggGender": {
"terms": {
/**
* 需要聚合操作的欄位名,**需要注意的是:對于text型別的欄位,
* 需要使用filed.keyword型別進行聚合,類似于查詢關鍵字term**
*/
"field": "field",
"size": n //聚合后展示的數量大小,默認10
}
}
}
例如下面的一段查詢操作:
GET info/_search
{
"query": {
"match": {
"address": "mill"
}
},
"aggs": {
"aggGender": {
"terms": {
"field": "gender.keyword",
"size": 10
}
}
}
}
上面的操作含義為:首先對address欄位進行模糊查詢,后面的聚合操作時基于前面的查詢結果進行聚合操作,按照性別進行聚合,也就是將"男"和"女"欄位的資料進行分組,結果如下所示
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4, //共查詢到4條資料
"relation" : "eq"
},
"max_score" : 5.4032025,
"hits" : [
{
這里為了方便展示全部資料,將查詢到的結果資料進行省略
}
]
},
//聚合函式結果
"aggregations" : {
"aggGender" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "M",
"doc_count" : 3 //表示查詢出來的4條資料中有3條是男性
},
{
"key" : "F",
"doc_count" : 1 //表示查詢出來的4條資料中有1條是女性
}
]
}
}
}
- 嵌套聚合操作
當我們想對上一步聚合后的結果進行更加細粒度化,就可以在原有基礎上再封裝一層聚合操作,比如我們需要得到從上述查詢出來的資料中,男女不同性別的平均薪水,
GET info/_search
{
"query": {
"match": {
"address": "mill"
}
},
"aggs": {
"aggGender": {
"terms": {
"field": "gender.keyword",
"size": 10
},
//在上一步聚合后,再進行一層嵌套聚合操作
"aggs": {
"aggBalanceAvg": {
"avg": { //基于前面的聚合資料獲取薪資均值
"field": "balance" //薪資欄位balance
}
}
}
}
}
}
輸出結果如下所示:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 4,
"relation" : "eq"
},
"max_score" : 5.4032025,
"hits" : [
{
這里為了方便展示全部資料,將查詢到的結果資料進行省略
}
]
},
"aggregations" : {
"aggGender" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "M",
"doc_count" : 3,
"aggBalanceAvg" : { //二次子聚合名稱
"value" : 25087.0 //男性中的平均薪水
}
},
{
"key" : "F",
"doc_count" : 1,
"aggBalanceAvg" : {
"value" : 25571.0 //女性中的平均薪水
}
}
]
}
}
}
好了,學到這里,你對es的基本入門操作已經大概了解了,下一遍將會繼續講解elasticsearch的高級客戶端的基本使用,也即整合到springboot的使用,
這是本人的第一篇博客,有不足之處還望各位老哥多多指點,后續將會持續輸出更多互聯網公司必備的技術和學習心得,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/289205.html
標籤:其他
上一篇:Kafka核心基礎——作業原理
下一篇:2021-07-19
