Elasticsearch簡介與實戰

什麼是Elasticsearch?

  Elasticsearch是一個開源的分佈式、RESTful 風格的搜索和數據分析引擎,它的底層是開源庫Apache Lucene。
  Lucene 能夠說是當下最早進、高性能、全功能的搜索引擎庫——不管是開源仍是私有,但它也僅僅只是一個庫。爲了充分發揮其功能,你須要使用 Java 並將 Lucene 直接集成到應用程序中。 更糟糕的是,您可能須要得到信息檢索學位才能瞭解其工做原理,由於Lucene 很是複雜。
  爲了解決Lucene使用時的繁複性,因而Elasticsearch便應運而生。它使用 Java 編寫,內部採用 Lucene 作索引與搜索,可是它的目標是使全文檢索變得更簡單,簡單來講,就是對Lucene 作了一層封裝,它提供了一套簡單一致的 RESTful API 來幫助咱們實現存儲和檢索。
  固然,Elasticsearch 不只僅是 Lucene,而且也不只僅只是一個全文搜索引擎。 它能夠被下面這樣準確地形容:java

  • 一個分佈式的實時文檔存儲,每一個字段能夠被索引與搜索;
  • 一個分佈式實時分析搜索引擎;
  • 能勝任上百個服務節點的擴展,並支持 PB 級別的結構化或者非結構化數據。

因爲Elasticsearch的功能強大和使用簡單,維基百科、衛報、Stack Overflow、GitHub等都紛紛採用它來作搜索。如今,Elasticsearch已成爲全文搜索領域的主流軟件之一。
  下面將介紹Elasticsearch的安裝與簡單使用。node

安裝並運行Elasticsearch

  安裝 Elasticsearch 以前,你須要先安裝一個較新版本的 Java,最好的選擇是,你能夠從 www.java.com 得到官方提供的最新版本的Java。
  你能夠從 elastic 的官網 elastic.co/downloads/elasticsearch 獲取最新版本的Elasticsearch。解壓文檔後,按照下面的操做,便可在前臺(foregroud)啓動 Elasticsearch:web

cd elasticsearch-<version>
./bin/elasticsearch

此時,Elasticsearch運行在本地的9200端口,在瀏覽器中輸入網址「http://localhost:9200/」,若是看到如下信息就說明你的電腦已成功安裝Elasticsearch:算法

{
  "name" : "YTK8L4q",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "hB2CZPlvSJavhJxx85fUqQ",
  "version" : {
    "number" : "6.5.4",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "d2ef93d",
    "build_date" : "2018-12-17T21:17:40.758843Z",
    "build_snapshot" : false,
    "lucene_version" : "7.5.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

在這裏,咱們安裝的Elasticsearch版本號爲6.5.4。
  Kibana 是一個開源的分析和可視化平臺,旨在與 Elasticsearch 合做。Kibana 提供搜索、查看和與存儲在 Elasticsearch 索引中的數據進行交互的功能。開發者或運維人員能夠輕鬆地執行高級數據分析,並在各類圖表、表格和地圖中可視化數據。
  你能夠從 elastic 的官網 https://www.elastic.co/downloads/kibana 獲取最新版本的Kibana。解壓文檔後,按照下面的操做,便可在前臺(foregroud)啓動Kibana:數據庫

cd kibana-<version>
./bin/kabana

此時,Kibana運行在本地的5601端口,在瀏覽器中輸入網址「http://localhost:5601」,便可看到如下界面:數組

Kibana啓動界面

  下面,讓咱們來了解Elasticsearch的一些基本概念,這有助於咱們更好地理解和使用Elasticsearch。瀏覽器

Elasticsearch基本概念

全文搜索(Full-text Search)

  全文檢索是指計算機索引程序經過掃描文章中的每個詞,對每個詞創建一個索引,指明該詞在文章中出現的次數和位置,當用戶查詢時,檢索程序就根據事先創建的索引進行查找,並將查找的結果反饋給用戶的檢索方式。
  在全文搜索的世界中,存在着幾個龐大的帝國,也就是主流工具,主要有:服務器

  • Apache Lucene
  • Elasticsearch
  • Solr
  • Ferret

倒排索引(Inverted Index)

  該索引表中的每一項都包括一個屬性值和具備該屬性值的各記錄的地址。因爲不是由記錄來肯定屬性值,而是由屬性值來肯定記錄的位置,於是稱爲倒排索引(inverted index)。Elasticsearch可以實現快速、高效的搜索功能,正是基於倒排索引原理。微信

節點 & 集羣(Node & Cluster)

  Elasticsearch 本質上是一個分佈式數據庫,容許多臺服務器協同工做,每臺服務器能夠運行多個Elasticsearch實例。單個Elasticsearch實例稱爲一個節點(Node),一組節點構成一個集羣(Cluster)。運維

索引(Index)

  Elasticsearch 數據管理的頂層單位就叫作 Index(索引),至關於關係型數據庫裏的數據庫的概念。另外,每一個Index的名字必須是小寫。

文檔(Document)

  Index裏面單條的記錄稱爲 Document(文檔)。許多條 Document 構成了一個 Index。Document 使用 JSON 格式表示。同一個 Index 裏面的 Document,不要求有相同的結構(scheme),可是最好保持相同,這樣有利於提升搜索效率。

類型(Type)

  Document 能夠分組,好比employee這個 Index 裏面,能夠按部門分組,也能夠按職級分組。這種分組就叫作 Type,它是虛擬的邏輯分組,用來過濾 Document,相似關係型數據庫中的數據表。
  不一樣的 Type 應該有類似的結構(Schema),性質徹底不一樣的數據(好比 products 和 logs)應該存成兩個 Index,而不是一個 Index 裏面的兩個 Type(雖然能夠作到)。

文檔元數據(Document metadata)

  文檔元數據爲_index, _type, _id, 這三者能夠惟一表示一個文檔,_index表示文檔在哪存放,_type表示文檔的對象類別,_id爲文檔的惟一標識。

字段(Fields)

  每一個Document都相似一個JSON結構,它包含了許多字段,每一個字段都有其對應的值,多個字段組成了一個 Document,能夠類比關係型數據庫數據表中的字段。
  在 Elasticsearch 中,文檔(Document)歸屬於一種類型(Type),而這些類型存在於索引(Index)中,下圖展現了Elasticsearch與傳統關係型數據庫的類比:

Elasticsearch入門

  Elasticsearch提供了多種交互使用方式,包括Java API和RESTful API ,本文主要介紹RESTful API 。全部其餘語言可使用RESTful API 經過端口 9200 和 Elasticsearch 進行通訊,你能夠用你最喜好的 web 客戶端訪問 Elasticsearch 。甚至,你還可使用 curl 命令來和 Elasticsearch 交互。
  一個Elasticsearch請求和任何 HTTP 請求同樣,都由若干相同的部件組成:

curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'

返回的數據格式爲JSON,由於Elasticsearch中的文檔以JSON格式儲存。其中,被 < > 標記的部件:

部件 說明
VERB 適當的 HTTP 方法 或 謂詞 : GETPOSTPUTHEAD 或者 DELETE
PROTOCOL http 或者 https(若是你在 Elasticsearch 前面有一個 https 代理)
HOST Elasticsearch 集羣中任意節點的主機名,或者用 localhost 表明本地機器上的節點。
PORT 運行 Elasticsearch HTTP 服務的端口號,默認是 9200 。
PATH API 的終端路徑(例如 _count 將返回集羣中文檔數量)。Path 可能包含多個組件,例如:_cluster/stats 和 _nodes/stats/jvm 。
QUERY_STRING 任意可選的查詢字符串參數 (例如 ?pretty 將格式化地輸出 JSON 返回值,使其更容易閱讀)
BODY 一個 JSON 格式的請求體 (若是請求須要的話)

對於HTTP方法,它們的具體做用爲:

HTTP方法 說明
GET 獲取請求對象的當前狀態
POST 改變對象的當前狀態
PUT 建立一個對象
DELETE 銷燬對象
HEAD 請求獲取對象的基礎信息

  咱們如下面的數據爲例,來展現Elasticsearch的用法。

如下所有的操做都在Kibana中完成,建立的index爲conference, type爲event .

插入數據

  首先建立index爲conference, 建立type爲event, 插入id爲1的第一條數據,只需運行下面命令就行:

PUT /conference/event/1
{
  "host": "Dave",
  "title": "Elasticsearch at Rangespan and Exonar",
  "description": "Representatives from Rangespan and Exonar will come and discuss how they use Elasticsearch",
  "attendees": ["Dave", "Andrew", "David", "Clint"],
  "date": "2013-06-24T18:30",
  "reviews": 3
}

在上面的命令中,路徑/conference/event/1表示文檔的index爲conference, type爲event, id爲1. 相似於上面的操做,依次插入剩餘的4條數據,完成插入後,查看數據以下:

插入數據

刪除數據

  好比咱們想要刪除conference中event裏面id爲5的數據,只需運行下面命令便可:

DELETE /conference/event/5

返回結果以下:

{
  "_index" : "conference",
  "_type" : "event",
  "_id" : "5",
  "_version" : 2,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

表示該文檔已成功刪除。若是想刪除整個event類型,可輸入命令:

DELETE /conference/event

若是想刪除整個conference索引,可輸入命令:

DELETE /conference
修改數據

  修改數據的命令爲POST, 好比咱們想要將conference中event裏面id爲4的文檔的做者改成Bob,那麼須要運行命令以下:

POST /conference/event/4/_update
{
  "doc": {"host": "Bob"}
}

返回的信息以下:(表示修改數據成功)

{
  "_index" : "conference",
  "_type" : "event",
  "_id" : "4",
  "_version" : 7,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 7,
  "_primary_term" : 1
}

查看修改後的數據以下:

修改數據

查詢數據

  查詢數據的命令爲GET,查詢命令也是Elasticsearch最爲重要的功能之一。好比咱們想查詢conference中event裏面id爲1的數據,運行命令以下:

GET /conference/event/1

返回的結果以下:

{
  "_index" : "conference",
  "_type" : "event",
  "_id" : "1",
  "_version" : 2,
  "found" : true,
  "_source" : {
    "host" : "Dave",
    "title" : "Elasticsearch at Rangespan and Exonar",
    "description" : "Representatives from Rangespan and Exonar will come and discuss how they use Elasticsearch",
    "attendees" : [
      "Dave",
      "Andrew",
      "David",
      "Clint"
    ],
    "date" : "2013-06-24T18:30",
    "reviews" : 3
  }
}

在_source 屬性中,內容是原始的 JSON 文檔,還包含有其它屬性,好比_index, _type, _id, _found等。
  若是想要搜索conference中event裏面全部的文檔,運行命令以下:

GET /conference/event/_search

返回結果包括了全部四個文檔,放在數組 hits 中。
  固然,Elasticsearch 提供更加豐富靈活的查詢語言叫作 查詢表達式 , 它支持構建更加複雜和健壯的查詢。利用查詢表達式,咱們能夠檢索出conference中event裏面全部host爲Bob的文檔,命令以下:

GET /conference/event/_search
{
    "query" : {
        "match" : {
            "host" : "Bob"
        }
    }
}

返回的結果只包括了一個文檔,放在數組 hits 中。
  接着,讓咱們嘗試稍微高級點兒的全文搜索——一項傳統數據庫確實很難搞定的任務。搜索下全部description中含有"use Elasticsearch"的event:

GET /conference/event/_search
{
    "query" : {
        "match" : {
            "description" : "use Elasticsearch"
        }
    }
}

返回的結果(部分)以下:

{
 ...
  "hits" : {
    "total" : 2,
    "max_score" : 0.65109104,
    "hits" : [
      {
        ...
        "_score" : 0.65109104,
        "_source" : {
          "host" : "Dave Nolan",
          "title" : "real-time Elasticsearch",
          "description" : "We will discuss using Elasticsearch to index data in real time",
          ...
        }
      },
      {
        ...
        "_score" : 0.5753642,
        "_source" : {
          "host" : "Dave",
          "title" : "Elasticsearch at Rangespan and Exonar",
          "description" : "Representatives from Rangespan and Exonar will come and discuss how they use Elasticsearch",
          ...
        }
      }
    ]
  }
}

返回的結果包含了兩個文檔,放在數組 hits 中。讓咱們對這個結果作一些分析,第一個文檔的description裏面含有「using Elasticsearch」,這個能匹配「use Elasticsearch」是由於Elasticsearch含有內置的詞幹提取算法,以後兩個文檔按_score進行排序,_score字段表示文檔的類似度(默認的類似度算法爲BM25)。
  若是想搜索下全部description中嚴格含有"use Elasticsearch"這個短語的event,可使用下面的命令:

GET /conference/event/_search
{
    "query" : {
        "match_phrase": {
            "description" : "use Elasticsearch"
        }
    }
}

這時候返回的結果只有一個文檔,就是上面輸出的第二個文檔。
  固然,Elasticsearch還支持更多的搜索功能,好比過濾器,高亮搜索,結構化搜索等,但願接下來能有更多的時間和經從來介紹~

總結

  後續有機會再介紹如何利用Python來操做Elasticsearch~
  本次分享到此結束,感謝你們閱讀~

注意:本人現已開通微信公衆號: Python爬蟲與算法(微信號爲:easy_web_scrape), 歡迎你們關注哦~~

相關文章
相關標籤/搜索