ElasticSearch

 ElasticSearch:html

ES是一個基於Lucene實現的開源、分佈式、Restful的全文本搜索引擎;此外,它仍是一個分佈式實時文檔存儲,其中每一個文檔的每一個field均是被索引的數據,且可被搜索;也是一個帶實時分析功能的分佈式搜索引擎,可以擴展至數以百計的節點實時處理PB級的數據。java

Lucene介紹:http://www.cnblogs.com/python-gm/p/8400001.html  

 基本組件:node

  • 索引(index):文檔容器,換句話說,索引是具備相似屬性的文檔的集合。相似於表。索引名必須使用小寫字母;
  • 類型(type):類型是索引內部的邏輯分區,其意義徹底取決於用戶需求。一個索引內部可定義一個或多個類型。通常來講,類型就是擁有相同的域的文檔的預約義。
  • 文檔(document):文檔是Lucene索引和搜索的原子單位,它包含了一個或多個域。是域的容器;基於JSON格式表示。
    • 每一個域的組成部分:一個名字,一個或多個值;擁有多個值的域,一般稱爲多值域;
  • 映射(mapping):原始內容存儲爲文檔以前須要事先進行分析,例如切詞、過濾掉某些詞等;映射用於定義此分析機制該如何實現;除此以外,ES還爲映射提供了諸如將域中的內容排序等功能。

 ES的集羣組件:python

  • Cluster:ES的集羣標識爲集羣名稱;默認爲"elasticsearch"。節點就是靠此名字來決定加入到哪一個集羣中。一個節點只能屬性於一個集羣。
  • Node:運行了單個ES實例的主機即爲節點。用於存儲數據、參與集羣索引及搜索操做。節點的標識靠節點名。
  • Shard:將索引切割成爲的物理存儲組件;但每個shard都是一個獨立且完整的索引;
    • 建立索引時,ES默認將其分割爲5個shard,每一個shard也會有一個副本,用戶也能夠按需自定義,建立完成以後不可修改。
    • shard有兩種類型:primary shard和replica。Replica用於數據冗餘及查詢時的負載均衡。每一個主shard的副本數量可自定義,且可動態修改。

 ES Cluster工做過程:json

  • 啓動時,經過多播(默認)或單播方式在9300/tcp查找同一集羣中的其它節點,並與之創建通訊。
  • 集羣中的全部節點會選舉出一個主節點負責管理整個集羣狀態,以及在集羣範圍內決定各shards的分佈方式。站在用戶角度而言,每一個都可接收並響應用戶的各種請求。
  • 集羣有狀態:green, red, yellow
官方站點:https://www.elastic.co/  

ElasticSearch依賴於JDK環境:能夠安裝配置 Oracle JDK 或 OpenJDK ubuntu

 ES的默認端口:緩存

  • 參與集羣的事務:9300/tcp
    • transport.tcp.port  
  • 接收請求:9200/tcp
    • http.port

 Restful API:bash

  • 四類API:
    • (1) 檢查集羣、節點、索引等健康與否,以及獲取其相應狀態;
    • (2) 管理集羣、節點、索引及元數據;  
    • (3) 執行CRUD操做;  
    • (4) 執行高級操做,例如paging, filtering等;  
  • ES訪問接口:9200/tcp
  • curl -X<VERB> '<PROTOCOL>://HOST:PORT/<PATH>?<QUERY_STRING>' -d '<BODY>'
    • VERB: GET, PUT, DELETE等;  
    • PROTOCOL: http, https  
    • QUERY_STRING:查詢參數,例如?pretty表示用易讀的JSON格式輸出;  
    • BODY: 請求的主體; 

 Cluster APIs:app

  • health:
curl -XGET 'http://172.16.100.67:9200/_cluster/health?pretty'  
  • state:
curl -XGET 'http://172.16.100.67:9200/_cluster/state/<metrics>?pretty'  
  • stats:
curl -XGET 'http://172.16.100.67:9200/_cluster/stats'  
  • 節點狀態:
curl -XGET 'http://172.16.100.67:9200/_nodes/stats'  

 Plugins:負載均衡

  • 插件擴展ES的功能:
    • 添加自定義的映射類型、自定義分析器、本地腳本、自定義發現方式;  
  • 安裝:
    • 直接將插件放置於plugins目錄中便可;  
    • 使用plugin腳本進行安裝;  
/usr/share/elasticsearch/bin/plugin -h
參數:
-l
-i, --install
-r, --remove  
  • 站點插件:
http://HOST:9200/_plugin/plugin_name  

 部署elasticsearch集羣:

  • 實驗環境
主機:Ubuntu16.04

elasticsearch版本:6.4.2  
  • 安裝java環境
sudo apt-get install default-jre

# 查看java版本
java -version

openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-0ubuntu0.16.04.1-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)  
  • 安裝elasticsearch
# 首先須要添加 Apt-key:
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

# 而後添加 Elasticsearch 的 Repository 定義:
echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.x.list

# 安裝 Elasticsearch:
sudo apt-get update 
sudo apt-get install elasticsearch

# 全部主機完成 Elasticsearch 的安裝  
  •  修改主機配置文件
cluster.name: evescn     ##集羣名稱,全部主機配置必須相同
node.name: node-1        ##節點名稱,不一樣主機此處名字不能相同
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
discovery.zen.ping.unicast.hosts: ["192.168.20.102", "192.168.20.103", "192.168.0.104"]        ## 集羣地址設置,配置以後集羣的主機之間能夠自動發現 
  •  查看集羣狀態
# curl -XGET 'http://localhost:9200/_cluster/state?pretty' | less
{
  "cluster_name" : "evescn",
  "compressed_size_in_bytes" : 10114,
  "cluster_uuid" : "lmV_adT3TTGt3kz5_IWeSA",
  "version" : 14,
  "state_uuid" : "c1pcj3nAS5-DyWoCcWXy5w",
  "master_node" : "LdRkSjSMSLKH7PtOwDHQIw",
  "blocks" : { },
  "nodes" : {
    "LdRkSjSMSLKH7PtOwDHQIw" : {
      "name" : "node-2",
      "ephemeral_id" : "nf0KaKZlQduuz3rWVzxhew",
      "transport_address" : "192.168.20.103:9300",
      "attributes" : {
        "ml.machine_memory" : "1021595648",
        "ml.max_open_jobs" : "20",
        "xpack.installed" : "true",
        "ml.enabled" : "true"
      }
    },
    "LR0zlOMbRF-kxX33VQLtCw" : {
      "name" : "node-3",
      "ephemeral_id" : "gX8srlZWR9GdU2W-B63KIw",
      "transport_address" : "192.168.20.104:9300",
      "attributes" : {
        "ml.machine_memory" : "1021595648",
        "ml.max_open_jobs" : "20",
        "xpack.installed" : "true",
        "ml.enabled" : "true"
      }
......
}
  • 插入數據進行查看
## 6.X新版本規則,須要指定 -H "Content-Type: application/json"

# A主機插入數據
# curl -H "Content-Type: application/json" -XPUT 'localhost:9200/students/class1/2?pretty' -d '
> {
>    "first_name": "gm",
>    "last_name": "evescn",
>    "gender": "Man",
>    "age": 23,
>    "courses": "ELK"
> }'

# B主機查看
# curl -XGET 'localhost:9200/students/class1/2?pretty'
{
  "_index" : "students",
  "_type" : "class1",
  "_id" : "2",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "first_name" : "gm",
    "last_name" : "evescn",
    "gender" : "Man",
    "age" : 23,
    "courses" : "ELK"
  }

  

 CRUD操做相關的API:

  • 建立文檔:
curl -XPUT 'localhost:9200/students/class1/2?pretty' -d '
> {
>   "first_name": "Rong",
>   "last_name": "Huang",
>   "gender": "Female",
>   "age": 23,
>   "courses": "Luoying Shenjian"
> }'
{
  "_index" : "students",
  "_type" : "class1",
  "_id" : "2",
  "_version" : 1,
  "created" : true
}   
  • 獲取文檔:
~]# curl -XGET 'localhost:9200/students/class1/2?pretty'
{
  "_index" : "students",
  "_type" : "class1",
  "_id" : "2",
  "_version" : 1,
  "found" : true,
  "_source":
{
  "first_name": "Rong",
  "last_name": "Huang",
  "gender": "Female",
  "age": 23,
  "courses": "Luoying Shenjian"
}  
  • 更新文檔:
    • PUT方法會覆蓋原有文檔;  
    • 若是隻更新部份內容,得使用_update API  
~]# curl -XPOST 'localhost:9200/students/class1/2/_update?pretty' -d '
{
  "doc": { "age": 22 }
}'
{
  "_index" : "students",
  "_type" : "class1",
  "_id" : "2",
  "_version" : 2
}  
  • 刪除文檔:
DETELE

~]# curl -XDELETE 'localhost:9200/students/class1/2'  
  • 刪除索引:
~]# curl -XDELETE 'localhost:9200/students'

~]# curl -XGET 'localhost:9200/_cat/indices?v'  

 查詢數據:

  • Query API
    • Query DSL:JSON based language for building complex queries.
    • 用戶實現諸多類型的查詢操做,好比,simple term query, phrase, range boolean, fuzzy等;  
  • ES的查詢操做執行分爲兩個階段:
    • 分散階段 
    • 合併階段 
  • 查詢方式:
    • 向ES發起查詢請求的方式有兩種:  
    • 一、經過Restful request API查詢,也稱爲query string;  
    • 二、經過發送REST request body進行;  
一、經過Restful request API查詢; 
  
~]# curl -XGET 'localhost:9200/students/_search?pretty'

二、經過發送REST request body進行;

~]# curl -XGET 'localhost:9200/students/_search?pretty' -d '
> {
> "query": { "match_all": {} }
> }'
  • 多索引、多類型查詢:
/_search:全部索引;

/INDEX_NAME/_search:單索引;

/INDEX1,INDEX2/_search:多索引;

/s*,t*/_search:正則匹配搜索

/students/class1/_search:單類型搜索

/students/class1,class2/_search:多類型搜索  

 Mapping和Analysis:

  • ES:對每個文檔,會取得其全部域的全部值,生成一個名爲「_all」的域;執行查詢時,若是在query_string未指定查詢的域,則在_all域上執行查詢操做;
GET /_search?q='Xianglong' :全部域中出現此字符串的值
GET /_search?q='Xianglong%20Shiba%20Zhang'
GET /_search?q=courses:'Xianglong%20Shiba%20Zhang' :在courses域中查詢此字符串
GET /_search?q=courses:'Xianglong'

前兩個:表示在_all域搜索;
後兩個:在指定的域上搜索;  
  • 數據類型:string, numbers, boolean, dates
  • 查看指定類型的mapping示例:
~]# curl 'localhost:9200/students/_mapping/class1?pretty'  
  • ES中搜索的數據廣義上可被理解爲兩類:
types:exact
full-text  
精確值:指未經加工的原始值;在搜索時進行精確匹配;
full-text:用於引用文本中數據;判斷文檔在多大程序上匹配查詢請求;即評估文檔與用戶請求查詢的相關度;  
    • 爲了完成full-text搜索,ES必須首先分析文本,並建立出倒排索引;倒排索引中的數據還需進行「正規化」爲標準格式;
      • 分詞    
      • 正規化 (分詞+正規化==》分析)    
    • 分析須要由分析器進行:analyzer  
      • 分析器由三個組件構成:字符過濾器、分詞器、分詞過濾器    
      • ES內置的分析器:    
Standard analyzer:
Simple analyzer
Whitespace analyzer
Language analyzer  
      • 分析器不只在建立索引時用到;在構建查詢時也會用到;
  • Query DSL:
request body:
    分紅兩類:
    query dsl:執行full-text查詢時,基於相關度來評判其匹配結果;查詢執行過程複雜,且不會被緩存;
    filter dsl:執行exact查詢時,基於其結果爲「yes」或「no」進行評判;速度快,且結果緩存;

  

查詢語句的結構:
{
    QUERY_NAME: {
        AGGUMENT: VALUE,
        ARGUMENT: VALUE,...
    }
}

{
    QUERY_NAME: {
        FIELD_NAME: {
            ARGUMENT: VALUE,...
        }
    }
}

  

  • filter dsl:
term filter:精確匹配包含指定term的文檔;
{ "term": {"name": "Guo"} } curl -XGET 'localhost:9200/students/_search?pretty' -d { "query": { "term": { "name": "Guo" } } }

  

terms filter:用於多值精確匹配;

{ "terms": { "name": ["Guo", "Rong"] }}

range filters:用於在指定的範圍內查找數值或時間。
{ "range": 
  "age": {
    "gte": 15,
    "lte": 25
  }
}

gt, lt, gte, lte  

 

exists and missing filters:存在或不存在
{ "exists": { "age": 25 } }  

 

boolean filter:

基於boolean的邏輯來合併多個filter子句;
must:其內部全部的子句條件必須同時匹配,即and;
must: {
  "term": { "age": 25 }
  "term": { "gender": "Female" }
}  

 

must_not:其全部子句必須不匹配,即not

must_not: {
  "term": { "age": 25 }
}  

 

should:至少有一個子句匹配,即or

should: {
  "term": { "age": 25 }
  "term": { "gender": "Female" }
}  
  • QUERY DSL:
match_all Query:

用於匹配全部文檔,沒有指定任何query,默認即爲match_all query.
{ "match_all": {} }

  

match Query:
在幾乎任何域上執行full-text或exact-value查詢;

若是執行full-text查詢:首先對查詢時的語句作分析;
{ "match": {"students": "Guo" }}

若是執行exact-value查詢:搜索精確值;此時,建議使用過濾,而非查詢;
{ "match": {"name": "Guo"} }  

 

multi_match Query:

用於在多個域上執行相同的查詢;
{
  "multi_match":
  "query": full-text search
  "field": {'field1', 'field2'}
}

{
  "multi_match":
  "query": {
    "students": "Guo"
  }
  "field":
  {
    "name",
    "description"
  }
}

  

bool query:
基於boolean邏輯合併多個查詢語句;與bool filter不一樣的是,查詢子句不是返回"yes"或"no",而是其計算出的匹配度分值。所以,boolean Query會爲各子句合併其score;

must:
must_not:
should:  

 

合併filter和query:

{
  "filterd": {
    query: { "match": {"gender": "Female"} }
    filter: { "term": {"age": 25}}
  }
}  
  • 查詢語句語法檢查:
GET /INDEX/_validate/query?pretty
{
...
}


GET /INDEX/_validate/query?explain&pretty
{
...
}  
相關文章
相關標籤/搜索