Elasticsearch學習 day2

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

  1. green:每個索引的primary shard和replica shard都是active狀態的
  2. yellow:每個索引的primary shard都是active狀態的,但是部分replica shard不是active狀態,處於不可用的狀態
  3. 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/id

    PUT /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"  // 使用函數的字段
                  }  
                }
              }
            }
          }
        }
      
      }
    }
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章