文章目錄
Elasticsearch學習的第二天
- 全文檢索:倒排索引
- Elasticsearch基於lucene實現:
一、ES核心概念
1. Near Realtime(NRT):近實時
從寫入數據到數據可以被搜索到有一個小延遲(大概1秒),基於es執行搜索和分析可以達到秒級。
2. Cluster:集羣
包含多個節點,每個節點屬於哪個集羣是通過一個配置(集羣名稱)來決定,對於中小型應用來說剛開始一個集羣就一個節點很正常。
3. Node:節點
集羣中的一個節點,節點也有一個名稱(默認隨機分配的),節點名稱很重要(在執行運維管理操作的時候),默認節點會去加入一個名稱爲”elasticsearch“的集羣,如果直接啓動一堆節點,那麼它們會自動組成一個elasticsearch集羣,當然一個節點也可以組成一個elasticsearch集羣。
4. Docment:文檔
es中的最小數據單元,一個docment可以是一條客戶數據,一條商品分類數據,一條訂單數據,通常用Json數據結構表示,每個index下的type中,都可以存儲多個docment。
5. Index:索引
包含一推有相似結構的文檔數據,比如,可以有一個客戶索引,商品分類索引,訂單索引,索引有一個名稱。
6. Type:類型
每個索引裏都可以有一個或多個type,type是index中的一個邏輯數據分類,一個type下的docment,都有相同的field,比如博客系統,有一個索引,包含用戶數據type,博客數據type,評論數據type。
7. shard:分片
單臺機器無法存儲大量數據,es可以將一個索引中的數據切分爲多個shard,分佈在多臺服務器上存儲。有了shard就可以橫向擴展,存儲更多數據讓搜索和分析操作分佈到多臺服務器上去執行,提升吞吐量和性能。每個shard都是一個lucene index。
8. replica:副本
任何一個服務器隨時都可能故障和宕機,此時shard可能就會丟失,因此可以爲每個shard創建多個replica副本。replica可以在shard故障時提供備用服務,保證數據不丟失,多個replica還可以提升搜索操作的吞吐量和性能。primary shard(建立索引時一次設置,不能修改,默認5個),replica shard(隨時修改數量,默認1個),默認每個索引10個shard,其中5個primary shard和5個repl shard,最小的高可用配置是2臺服務器。
二、ES的CRUD操作
在kibana裏的Dev Tools操作
1、docment數據格式:
- 應用系統的數據結構都是面向對象的,複雜的。
- 對象數據存儲到數據庫中,只能拆解開來,變爲扁平的多張表,每次查詢的時候還得還原回對象格式,相對麻煩。
- es是面向文檔的,文檔中存儲的數據結構,與面向對象的數據結構是一致的,基於這種文檔數據結構,es可以提供複雜的索引,全文檢索,分析聚合等功能。
- es的docment用json數據格式來表達。
2、簡單的集羣操作:
- 快速檢查集羣健康狀況:
GET /_cat/health?v
// 顯示如下:
epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1581080440 13:00:40 elasticsearch yellow 1 1 6 6 0 0 6 0 - 50.0%
健康狀態?green、yellow、red
- green:每個索引的primary shard和replica shard都是active狀態的
- yellow:每個索引的primary shard都是active狀態的,但是部分replica shard不是active狀態,處於不可用的狀態
- red:不是所有索引的primary shard都是active的,部分索引有數據丟失了
- 快速查看集羣中有哪些索引:
GET /_cat/indices?v
// 顯示如下:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open bigdata 5PzFnw5mShehmgi7df5JbQ 5 1 2 0 9kb 9kb
yellow open .kibana YIpzq22dTvW_kIs5VgS0yw 1 1 1 0 3.2kb 3.2kb
-
簡單的索引操作:
創建索引:PUT /test_index?pretty
刪除索引:
DELETE /test_index?pretty
-
docment全局替換:
PUT test/type/1 { "name":xxx, "age":20 }
-
docment強制創建:
PUT test/type/1/_create { "name":xxx, "age":20 }
-
docment的刪除:
DELETE test/type/1
3、CURD操作:
-
3.1 新增商品:新增文檔,建立索引
語法: PUT index/type/idPUT /ecommerce/product/1 { "name":"高露潔牙膏", "desc":"高效美白", "price":30, "producer":"高露潔廠家", "tags":["美白","防蛀"] } PUT /ecommerce/product/2 { "name":"佳潔士牙膏", "desc":"有效防蛀", "price":25, "producer":"佳潔士廠家", "tags":["防蛀"] } PUT /ecommerce/product/3 { "name":"中華牙膏", "desc":"草本植物", "price":18, "producer":"中華廠家", "tags":["清新","防蛀"] }
es會自動建立index和type,不需要提前建立,而且es默認會對docment每個field都建立倒排索引,讓其可以被搜索。
-
3.2 查詢商品:檢索文檔
語法: GET ecommerce/product/1 -
3.3 修改商品:替換文檔
PUT /ecommerce/product/3 { "name":"中華牙膏3", "desc":"草本植物3", "price":18, "producer":"中華廠家", "tags":["清新","防蛀"] }
-
3.4 修改商品:更新文檔
POST /ecommerce/product/3/_update { "doc":{ "name":"中華牙膏", "desc":"草本植物3", "price":58 } }
-
3.5 刪除商品:刪除文檔
DELETE /ecommerce/product/3?pretty
4、搜索方式:
-
4.1 query string search
搜索全部商品:GET ecommerce/product/_search
搜素全部的商品名稱中包含”牙膏“的商品,而且按照售價降序排序:
GET ecommerce/product/_search?q=name:牙膏&sort=price:desc
- 返回值詳解:
took:耗時,毫秒
time_out:是否超時
_shards:
hits:查詢結果
hits.total:查詢結果數量
hits.max_score:docment對於一個search的相關匹配分數
hits.hits:包含了匹配搜索的docment的詳細數據 - 適應於臨時在命令行使用一些工具,不如curl,快速發出請求,來檢索想要的信息,但是如果查詢很複雜是很難構建的,在生產環境中,幾乎很少很少使用。
- 返回值詳解:
-
4.2 query DSL
全稱:Domain Specified Language,把查詢的語句放到請求體中,使用json的格式來構建查詢語法,比較方便,可以構建各種複雜的語法。
搜索全部商品:GET ecommerce/product/_search { "query":{"match_all":{}} }
搜素全部的商品名稱中包含”牙膏“的商品,而且按照售價降序排序:
GET ecommerce/product/_search { "query": { "match": { "name": "牙膏" } }, "sort": [ { "price": { "order": "asc" } } ] }
分頁查詢商品:
從第幾個商品開始,查幾個,0代表第一個商品GET ecommerce/product/_search { "query": {"match_all": {}}, "from": 1, "size": 2 }
指定顯示查詢出的商品名稱和價格:
GET ecommerce/product/_search { "query": {"match_all": {}}, "_source":["name","price"] }
-
4.3 query filter
對數據進行過濾
搜索商品名稱包含”牙膏“,而且售價大於25的:GET ecommerce/product/_search { "query": { "bool": { "must":{ "match":{ "name":"牙膏" } }, "filter": { "range": { "price": { "gt": 2 } } } } } }
-
4.4 全文檢索
GET ecommerce/product/_search { "query": { "match": { "producer": "牙膏廠家" } } }
-
4.5 短語搜索(phrase search)
跟全文檢索相對反,全文檢索會將輸入的搜索串拆解開來,去倒排索引裏面去一一匹配,只有能匹配上任意一個拆解後的單詞,就可以作爲結果返回,而phrase search,要求輸入的搜索串,必須在指定的字段文本中,完全包含一模一樣的纔可以算匹配,才能返回結果。GET ecommerce/product/_search { "query": { "match_phrase": { "producer": "牙膏廠家" } } }
-
4.6 高亮搜索結果(phrase search)
GET ecommerce/product/_search { "query": { "match": { "name": "牙膏" } }, "highlight": { "fields": { "name": {} } } }
5、聚合查詢:
設置tags的fielddata屬性true
PUT ecommerce/_mapping/product
{
"properties": {
"tags":{
"type": "text",
"fielddata": true
}
}
}
-
計算每個tags下的商品數量,分組聚合
GET ecommerce/product/_search { "size": 0, // 顯示原始幾條數據 "aggs": { "group_by_tags": { // 自定義名稱 "terms": { "field": "tags", "size": 10 } } } }
-
對包含”牙膏“的商品,計算每個tags下的商品數量,先搜索再分組聚合
GET ecommerce/product/_search { "query": { "match": { "name": "牙膏" } }, "size": 0, "aggs": { "group_by_tags": { "terms": { "field": "tags", "size": 10 } } } }
-
計算每個tags下的商品數量,並計算它們的平均價格,分組聚合後再聚合
GET ecommerce/product/_search { "size": 0, "aggs": { "groug_by_tags": { "terms": { "field": "tags" }, "aggs": { "avg_price": { "avg": { "field": "price" } } } } } }
-
計算每個tags下的商品平均價格,並且按照平均價格降序排序
GET ecommerce/product/_search { "size": 0, "aggs": { "groug_by_tags": { "terms": { "field": "tags", "order": {"avg_price": "desc" } }, "aggs": { "avg_price": { "avg": { "field": "price" } } } } } }
-
按照指定的價格區間進行分組,然後在每組內再按照tag進行分組,最後再計算每組的平均價格
GET ecommerce/product/_search { "size": 0, "aggs": { // 聚合函數 "group_by_price": { // 自定義函數名 "range": { // 使用範圍函數 "field": "price", // 使用函數的字段 "ranges": [ // 範圍 { "from": 0, "to": 24 }, { "from": 25, "to": 50 } ] }, "aggs": { // 嵌套聚合函數 "group_by_tags": { // 自定義函數名 "terms": { // 分組函數 "field": "tags" // 使用函數的字段 }, "aggs": { // 嵌套聚合函數 "avg_price": { // 自定義函數名 "avg": { // 平均函數 "field": "price" // 使用函數的字段 } } } } } } } }