二、ElasticSearch基本操作
1、RESTful
- REST 指的是一組架構約束條件和原則,滿足這些約束條件和原則的應用程式或設計就是 RESTful,Web 應用程式最重要的 REST 原則是,客戶端和服務器之間的互動在請求之間是無狀態的,從客戶端到服務器的每個請求都必須包含理解請求所必需的資訊,如果服務器在請求之間的任何時間點重啟,客戶端不會得到通知,此外,無狀態請求可以由任何可用服務器回答,這十分適合云計算之類的環境,客戶端可以快取資料以改進性能,
- 在服務器端,應用程式狀態和功能可以分為各種資源,資源是一個有趣的概念物體,它向客戶端公開,資源的例子有:應用程式物件、資料庫記錄、演算法等等,每個資源都使用 URI (Universal Resource Identifier) 得到一個唯一的地址,所有資源都共享統一的介面,以便在客戶端和服務器之間傳輸狀態,使用的是標準的 HTTP 方法,比如 GET、PUT、POST 和DELETE,
- 在 REST 樣式的 Web 服務中,每個資源都有一個地址,資源本身都是方法呼叫的目標,方法串列對所有資源都是一樣的,這些方法都是標準方法,包括 HTTP GET、POST、PUT、DELETE,還可能包括 HEAD 和 OPTIONS,簡單的理解就是,如果想要訪問互聯網上的資源,就必須向資源所在的服務器發出請求,請求體中必須包含資源的網路路徑,以及對資源進行的操作(增刪改查),
2、Es的資料格式
- Elasticsearch 是面向檔案型資料庫,一條資料在這里就是一個檔案,為了方便大家理解,我們將 Elasticsearch 里存盤檔案資料和關系型資料庫 MySQL 存盤資料的概念進行一個類比

- ES 里的 Index 可以看做一個庫,而 Types 相當于表,Documents 則相當于表的行,這里 Types 的概念已經被逐漸榷訓,Elasticsearch 6.X 中,一個 index 下已經只能包含一個type,Elasticsearch 7.X 中, Type 的概念已經被洗掉了,
3、Http操作
-
索引操作
-
創建索引
-
對比關系型資料庫,創建索引就等同于創建資料庫
-
在 Postman 中,向 ES 服務器發 PUT 請求 :http://127.0.0.1:9200/class
-
請求后,服務器回傳回應
-

-
{ "acknowledged"【回應結果】: true, # true 操作成功 "shards_acknowledged"【分片結果】: true, # 分片操作成功 "index"【索引名稱】: "shopping" } # 注意:創建索引庫的分片數默認 1 片,在 7.0.0 之前的 Elasticsearch 版本中,默認 5 片
-
-
如果重復添加索引,會回傳錯誤資訊
-
-
查看所有索引
- 在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/_cat/indices?v
- 這里請求路徑中的_cat 表示查看的意思,indices 表示索引,所以整體含義就是查看當前 ES服務器中的所有索引,就好像 MySQL 中的 show tables 的感覺,服務器回應結果如下:
- 在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/_cat/indices?v
-
查看單個索引
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/class
-
查看索引向 ES 服務器發送的請求路徑和創建索引是一致的,但是 HTTP 方法不一致,這里可以體會一下 RESTful 的意義,請求后,服務器回應結果如下:
-

-
{ "shopping"【索引名】: { "aliases"【別名】: {}, "mappings"【映射】: {}, "settings"【設定】: { "index"【設定 - 索引】: { "creation_date"【設定 - 索引 - 創建時間】: "1627635260805", "number_of_shards"【設定 - 索引 - 主分片數量】: "1", "number_of_replicas"【設定 - 索引 - 副分片數量】: "1", "uuid"【設定 - 索引 - 唯一標識】: "SH-TMF4IS7-z1OlfuA7soQ", "version"【設定 - 索引 - 版本】: { "created": "7080099" }, "provided_name"【設定 - 索引 - 名稱】: "class" } } } }
-
-
-
洗掉索引
- 在 Postman 中,向 ES 服務器發 DELETE 請求 :http://127.0.0.1:9200/class
- 重新訪問索引時,服務器回傳回應:索引不存在
- 在 Postman 中,向 ES 服務器發 DELETE 請求 :http://127.0.0.1:9200/class
-
-
檔案操作
-
-
創建檔案
索引已經創建好了,接下來我們來創建檔案,并添加資料,這里的檔案可以類比為關系型資料庫中的表資料,添加的資料格式為 JSON 格式
-
在 Postman 中,向 ES 服務器發 POST 請求 :http://127.0.0.1:9200/class**/_doc**
-
請求體內容為:
-
{ "name":"張三", "age":18 } -

-
-
此處發送請求的方式必須為 POST,不能是 PUT,否則會發生錯誤
-
Post方法,服務器回應結果如下:
-

-
{ "_index"【索引】: "class", "_type"【型別-檔案】: "_doc", "_id"【唯一標識】: "yiGm9noBj0KWx1uYq8K1", #可以類比為 MySQL 中的主鍵,隨機生成 "_version"【版本】: 1, "result"【結果】: "created", #這里的 create 表示創建成功 "_shards"【分片】: { "total"【分片 - 總數】: 2, "successful"【分片 - 成功】: 1, "failed"【分片 - 失敗】: 0 }, "_seq_no": 0, "_primary_term": 1 }
-
-
上面的資料創建后,由于沒有指定資料唯一性標識(ID),默認情況下,ES 服務器會隨機生成一個,如果想要自定義唯一性標識,需要在創建時指定:http://127.0.0.1:9200/class/_doc/1
-
此處需要注意:如果增加資料時明確資料主鍵,那么請求方式也可以為 PUT
-
-
查看檔案
查看檔案時,需要指明檔案的唯一性標識,類似于 MySQL 中資料的主鍵查詢
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/class**/_doc/1**
-
查詢成功后,服務器回應結果:
-

-
{ "_index"【索引】: "class", "_type"【檔案型別】: "_doc", "_id": "1", "_version": 1, "_seq_no": 2, "_primary_term": 1, "found": true, "_source"【檔案源資訊】: { "name": "李四", "age": 24 } }
-
-
-
修改檔案
和新增檔案一樣,輸入相同的 URL 地址請求,如果請求體變化,會將原有的資料內容覆寫
-
在 Postman 中,向 ES 服務器發 POST 請求 :http://127.0.0.1:9200/class**/_doc/1**
-
請求體內容為:
-
{ "name":"李四123", "age":24 } -

-
-
修改成功后,服務器回應結果:
-

-
{ "_index": "class", "_type": "_doc", "_id": "1", "_version"【版本】: 2, "result"【結果】: "updated", # updated 表示資料被更新 "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 3, "_primary_term": 1 }
-
-
-
修改欄位
修改資料時,也可以只修改某一給條資料的區域資訊
-
在 Postman 中,向 ES 服務器發 POST 請求 :http://127.0.0.1:9200/class/_update/1
-
請求頭內容:
-
{ "doc": { "age": 1 } } -

-
-
修改成功后,服務器回應結果:
-
根據唯一性標識,查詢檔案資料,檔案資料已經更新
-
-
洗掉檔案
洗掉一個檔案不會立即從磁盤上移除,它只是被標記成已洗掉(邏輯洗掉),
-
在 Postman 中,向 ES 服務器發 DELETE 請求 :http://127.0.0.1:9200/class**/_doc/1**
-
洗掉成功,服務器回應結果:
-

-
{ "_index": "class", "_type": "_doc", "_id": "1", "_version"【版本】: 4, #對資料的操作,都會更新版本 "result"【結果】: "deleted", # deleted 表示資料被標記為洗掉 "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 5, "_primary_term": 1 }
-
-
洗掉后再查詢當前檔案資訊
-
如果洗掉一個并不存在的檔案
-

-

-
{ "_index": "class", "_type": "_doc", "_id": "1", "_version": 1, "result"【結果】: "not_found", # not_found 表示未查找到 "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 6, "_primary_term": 1 }
-
-
-
條件洗掉檔案
一般洗掉資料都是根據檔案的唯一性標識進行洗掉,實際操作時,也可以根據條件對多條資料進行洗掉
-
向 ES 服務器發 POST 請求 :http://127.0.0.1:9200/class/_delete_by_query
-
請求體內容為:
-
{ "query" : { "match" : { "age" : 3 } } } -

-
-
洗掉成功后,服務器回應結果:
-

-
{ "took"【耗時】: 85, "timed_out"【是否超時】: false, "total"【總數】: 3, "deleted"【洗掉數量】: 3, "batches": 1, "version_conflicts": 0, "noops": 0, "retries": { "bulk": 0, "search": 0 }, "throttled_millis": 0, "requests_per_second": -1.0, "throttled_until_millis": 0, "failures": [] }
-
-
-
-
-
映射操作
? 接下來就需要建索引庫(index)中的映射了,類似于資料庫(database)中的表結構(table),創建資料庫表需要設定欄位名稱,型別,長度,約束等;索引庫也一樣,需要知道這個型別下有哪些欄位,每個欄位有哪些約束資訊,這就叫做映射(mapping),
-
創建映射
-
在 Postman 中,向 ES 服務器發 PUT 請求 :http://127.0.0.1:9200/student**/_mapping**
-
請求體內容為:
-
{ "properties" : { "name" : { "type" : "text", "index" : true }, "sex" : { "type" : "text", "index" : false }, "age" : { "type" : "long", "index" : false } } } -

-
-
服務器回應結果如下:
-
映射資料說明:
- 欄位名:任意填寫,下面指定許多屬性,例如:title、subtitle、images、price
- type:型別,Elasticsearch 中支持的資料型別非常豐富,說幾個關鍵的:
- String 型別,又分兩種:
- text:可分詞
- keyword:不可分詞,資料會作為完整欄位進行匹配
- Numerical:數值型別,分兩類
- 基本資料型別:long、integer、short、byte、double、float、half_float
- 浮點數的高精度型別:scaled_float
- Date:日期型別
- Array:陣列型別
- Object:物件
- index:是否索引,默認為 true,也就是說你不進行任何配置,所有欄位都會被索引,
- true:欄位會被索引,則可以用來進行搜索
- alse:欄位不會被索引,不能用來搜索
- store:是否將資料進行獨立存盤,默認為 false
- 原始的文本會存盤在_source 里面,默認情況下其他提取出來的欄位都不是獨立存盤的,是從_source 里面提取出來的,當然你也可以獨立的存盤某個欄位,只要設定 “store”: true 即可,獲取獨立存盤的欄位要比從_source 中決議快得多,但是也會占用更多的空間,所以要根據實際業務需求來設定,
- analyzer:分詞器,這里的 ik_max_word 即使用 ik 分詞器,后面會有專門的章節學習
- String 型別,又分兩種:
-
-
查看映射
- 在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student**/_mapping**
- 服務器回應結果如下:
- 在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student**/_mapping**
-
索引映射關聯
-
在 Postman 中,向 ES 服務器發 PUT 請求 :http://127.0.0.1:9200/student1
-
請求體內容:
-
{ "setting" : {}, "mappings" : { "properties" : { "name" : { "type" : "test", "index" : true }, "sex" : { "type" : "test", "index" : false }, "age" : { "type" : "long", "index" : false } } } } -

-
-
服務器回應結果如下:
-
-
-
高級查詢
Elasticsearch 提供了基于 JSON 提供完整的查詢 DSL 來定義查詢
-
查詢所有檔案
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
{ "query": { "match_all": {} } } # "query":這里的 query 代表一個查詢物件,里面可以有不同的查詢屬性 # "match_all":查詢型別,例如:match_all(代表查詢所有), match,term , range 等等 # {查詢條件}:查詢條件會根據型別的不同,寫法也有差異 -

-
-
服務器回應結果如下:
-

-

-
{ "took【查詢花費時間,單位毫秒】" : 1116, "timed_out【是否超時】" : false, "_shards【分片資訊】" : { "total【總數】" : 1, "successful【成功】" : 1, "skipped【忽略】" : 0, "failed【失敗】" : 0 }, "hits【搜索命中結果】" : { "total"【搜索條件匹配的檔案總數】: { "value"【總命中計數的值】: 3, "relation"【計數規則】: "eq" # eq 表示計數準確, gte 表示計數不準確 }, "max_score【匹配度分值】" : 1.0, "hits【命中結果集合】" : [ ... } ] } }
-
-
-
匹配查詢
match 匹配型別查詢,會把查詢條件進行分詞,然后進行查詢,多個詞條之間是 or 的關系
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
請求體內容:
-
{ "query" : { "match" : { "name" : "張三" } } } -

-
-
服務器回應結果為:
-
-
欄位匹配查詢
multi_match 與 match 類似,不同的是它可以在多個欄位中查詢,
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
請求體內容:
-
{ "query": { "multi_match": { "query": "張三", "fields": ["name"] } } } -

-
-
服務器回應結果:
-
-
關鍵字精確查詢
term 查詢,精確的關鍵詞匹配查詢,不對查詢條件進行分詞
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
請求頭內容:
-
{ "query": { "term": { "name": { "value": "zhangsan" } } } } -

-
-
服務器回應結果:
- [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-s8NPBXUp-1627719867392)(E:\資料\博客\Java\ElasticSearch\image\關鍵字精確查詢2.png)]
-
-
多關鍵字精確查詢.
terms 查詢和 term 查詢一樣,但它允許你指定多值進行匹配,
如果這個欄位包含了指定值中的任何一個值,那么這個檔案滿足條件,類似于 mysql 的 in
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
{ "query" : { "terms" : { "name" : ["zhangsan", "lisi"] } } } -

-
-
服務器回應結果:
-
-
指定查詢欄位
默認情況下,Elasticsearch 在搜索的結果中,會把檔案中保存在_source 的所有欄位都回傳,
如果我們只想獲取其中的部分欄位,我們可以添加_source 的過濾
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "_source" : ["name", "nickname"], "query" : { "terms" : { "name" : ["zhangsan", "lisi"] } } } -

-
-
服務器回應結果:
-
-
過濾欄位
-
我們也可以通過:
- includes:來指定想要顯示的欄位
- excludes:來指定不想要顯示的欄位
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "_source" : { "includes" : ["name", "nickname"] }, "query" : { "terms" : { "name" : ["zhangsan", "lisi"] } } } -

-
-
服務器回應結果:
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求頭內容 { "_source" : { "excludes" : ["name", "nickname"] }, "query" : { "terms" : { "name" : ["zhangsan", "lisi"] } } } -

-
-
服務器回應結果:
-
-
組合查詢
bool把各種其它查詢通過must(必須 )、must_not(必須不)、should(應該)的方式進行組合-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "query" : { "bool" : { "must" : [ { "match" : { "name" : "zhangsan" } } ], "must_not" : [ { "match" : { "age" : "40" } } ], "should" : [ { "match" : { "sex" : "男" } } ] } } }
-
-
服務器回應結果:
-
-
范圍查詢
range 查詢找出那些落在指定區間內的數字或者時間,range 查詢允許以下字符

-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "query" : { "range" : { "age" : { "gte" : 30, "lte" : 35 } } } } -

-
-
服務器回應結果:
-
-
模糊查詢
? 回傳包含與搜索字詞相似的字詞的檔案,編輯距離是將一個術語轉換為另一個術語所需的一個字符更改的次數,這些更改可以包括:
- 更改字符(box → fox)
- 洗掉字符(black → lack)
- 插入字符(sic → sick)
- 轉置兩個相鄰字符(act → cat)
為了找到相似的術語,fuzzy 查詢會在指定的編輯距離內創建一組搜索詞的所有可能的變體或擴展,然后查詢回傳每個擴展的完全匹配,
通過 fuzziness 修改編輯距離,一般使用默認值 AUTO,根據術語的長度生成編輯距離,
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "query" : { "fuzzy" : { "name" : { "value" : "zhangsan" } } } } -

-
-
服務器回應結果:
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "query" : { "fuzzy" : { "name" : { "value" : "zhangsan", "fuzziness" : 0 } } } } -

-
-
服務器回應結果:
-
單欄位排序
sort 可以讓我們按照不同的欄位進行排序,并且通過 order 指定排序的方式,desc 降序,asc升序,
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "query" : { "match_all" : { } }, "sort" : [{ "age" : { "order" : "desc" } }] } -

-
-
服務器回應結果:
-
-
多欄位排序
假定我們想要結合使用 age 和 _score 進行查詢,并且匹配的結果首先按照年齡排序,然后按照相關性得分排序
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "query" : { "match_all" : { } }, "sort" : [ { "age" : { "order" : "desc" } }, { "_score" : { "order" : "desc" } } ] } -

-
-
服務器回應結果:
-
-
高亮查詢
在進行關鍵字搜索時,搜索出的內容中的關鍵字會顯示不同的顏色,稱之為高亮,
Elasticsearch 可以對查詢內容中的關鍵字部分,進行標簽和樣式(高亮)的設定,
在使用 match 查詢的同時,加上一個 highlight 屬性:
- pre_tags:前置標簽
- post_tags:后置標簽
- fields:需要高亮的欄位
- title:這里宣告 title 欄位需要高亮,后面可以為這個欄位設定特有配置,也可以空
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "query" : { "match" : { "name" : "zhangsan" } }, "highlight" : { "pre_tags" : "<font color = 'red'>", "post_tags" : "</font>", "fields" : { "name" : {} } } } -

-
-
服務器回應結果:
-
分頁查詢
from:當前頁的起始索引,默認從 0 開始, from = (pageNum - 1) * size
size:每頁顯示多少條
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "query" : { "match_all" : { } }, "sort" : [ { "age" : { "order" : "desc" } } ], "from" : 0, "size" : 2 } -

-
-
服務器回應結果:
-
-
聚合查詢
聚合允許使用者對 es 檔案進行統計分析,類似與關系型資料庫中的 group by,當然還有很多其他的聚合,例如取最大值、平均值等等,
對某個欄位取最大值 max
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "aggs" : { "max_age" : { "max" : {"field" : "age"} } }, "size" : 0 } -

-
-
服務器回應結果:
對某個欄位取最小值 min
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "aggs" : { "min_age" : { "min" : {"field" : "age"} } }, "size" : 0 } -

-
-
服務器回應結果:
對某個欄位求和 sum
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "aggs" : { "sum_age" : { "sum" : {"field" : "age"} } }, "size" : 0 } -

-
-
服務器回應結果:
對某個欄位取平均值 avg
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "aggs" : { "avg_age" : { "avg" : {"field" : "age"} } }, "size" : 0 } -

-
-
服務器回應結果:
對某個欄位的值進行去重之后再取總數
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "aggs" : { "distinct_age" : { "cardinality" : {"field" : "age"} } }, "size" : 0 } -

-
-
服務器回應結果:
Stats 聚合
? stats 聚合,對某個欄位一次性回傳 count,max,min,avg 和 sum 五個指標
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "aggs" : { "stats_age" : { "stats" : {"field" : "age"} } }, "size" : 0 } -

-
-
服務器回應結果:
-
-
桶聚合查詢
桶聚和相當于 sql 中的 group by 陳述句
terms 聚合,分組統計
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "aggs" : { "age_groupby" : { "terms" : {"field" : "age"} } }, "size" : 0 } -

-
-
服務器回應結果:
在 terms 分組下再進行聚合
-
在 Postman 中,向 ES 服務器發 GET 請求 :http://127.0.0.1:9200/student/_search
-
#請求體內容 { "aggs" : { "age_groupby" : { "terms" : {"field" : "age"}, "aggs" : { "sum_age" : { "sum" : {"field" : "age"} } } } }, "size" : 0 } -

-
-
服務器回應結果:
-
-
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/291421.html
標籤:其他














































