1. 程式人生 > 實用技巧 >Elasticsearch簡介與實戰

Elasticsearch簡介與實戰

什麼是Elasticsearch?

  Elasticsearch是一個開源的分散式、RESTful 風格的搜尋和資料分析引擎,它的底層是開源庫Apache Lucene。
  Lucene 可以說是當下最先進、高效能、全功能的搜尋引擎庫——無論是開源還是私有,但它也僅僅只是一個庫。為了充分發揮其功能,你需要使用 Java 並將 Lucene 直接整合到應用程式中。 更糟糕的是,您可能需要獲得資訊檢索學位才能瞭解其工作原理,因為Lucene 非常複雜。
  為了解決Lucene使用時的繁複性,於是Elasticsearch便應運而生。它使用 Java 編寫,內部採用 Lucene 做索引與搜尋,但是它的目標是使全文檢索變得更簡單,簡單來說,就是對Lucene 做了一層封裝,它提供了一套簡單一致的 RESTful API 來幫助我們實現儲存和檢索。

  當然,Elasticsearch 不僅僅是 Lucene,並且也不僅僅只是一個全文搜尋引擎。 它可以被下面這樣準確地形容:

  • 一個分散式的實時文件儲存,每個欄位可以被索引與搜尋;
  • 一個分散式實時分析搜尋引擎;
  • 能勝任上百個服務節點的擴充套件,並支援 PB 級別的結構化或者非結構化資料。

由於Elasticsearch的功能強大和使用簡單,維基百科、衛報、Stack Overflow、GitHub等都紛紛採用它來做搜尋。現在,Elasticsearch已成為全文搜尋領域的主流軟體之一。
  下面將介紹Elasticsearch的安裝與簡單使用。

安裝並執行Elasticsearch

  安裝 Elasticsearch 之前,你需要先安裝一個較新版本的 Java,最好的選擇是,你可以從 www.java.com 獲得官方提供的最新版本的Java。
  你可以從 elastic 的官網 elastic.co/downloads/elasticsearch 獲取最新版本的Elasticsearch。解壓文件後,按照下面的操作,即可在前臺(foregroud)啟動 Elasticsearch:

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還支援更多的搜尋功能,比如過濾器,高亮搜尋,結構化搜尋等,希望接下來能有更多的時間和經歷來介紹~



作者:山陰少年
連結:https://www.jianshu.com/p/d48c32423789
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。