什么是Elasticsearch?
??Elasticsearch是一個開源的分布式、RESTful 風格的搜索和數(shù)據(jù)分析引擎,它的底層是開源庫Apache Lucene。
??Lucene 可以說是當下最先進、高性能、全功能的搜索引擎庫——無論是開源還是私有,但它也僅僅只是一個庫。為了充分發(fā)揮其功能,你需要使用 Java 并將 Lucene 直接集成到應用程序中。 更糟糕的是,您可能需要獲得信息檢索學位才能了解其工作原理,因為Lucene 非常復雜。
??為了解決Lucene使用時的繁復性,于是Elasticsearch便應運而生。它使用 Java 編寫,內部采用 Lucene 做索引與搜索,但是它的目標是使全文檢索變得更簡單,簡單來說,就是對Lucene 做了一層封裝,它提供了一套簡單一致的 RESTful API 來幫助我們實現(xiàn)存儲和檢索。
??當然,Elasticsearch 不僅僅是 Lucene,并且也不僅僅只是一個全文搜索引擎。 它可以被下面這樣準確地形容:
- 一個分布式的實時文檔存儲,每個字段可以被索引與搜索;
- 一個分布式實時分析搜索引擎;
- 能勝任上百個服務節(jié)點的擴展,并支持 PB 級別的結構化或者非結構化數(shù)據(jù)。
由于Elasticsearch的功能強大和使用簡單,維基百科、衛(wèi)報、Stack Overflow、GitHub等都紛紛采用它來做搜索。現(xiàn)在,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 索引中的數(shù)據(jù)進行交互的功能。開發(fā)者或運維人員可以輕松地執(zhí)行高級數(shù)據(jù)分析,并在各種圖表、表格和地圖中可視化數(shù)據(jù)。
??你可以從 elastic 的官網 https://www.elastic.co/downloads/kibana 獲取最新版本的Kibana。解壓文檔后,按照下面的操作,即可在前臺(foregroud)啟動Kibana:
cd kibana-<version>
./bin/kabana
此時,Kibana運行在本地的5601端口,在瀏覽器中輸入網址“http://localhost:5601”,即可看到以下界面:
??下面,讓我們來了解Elasticsearch的一些基本概念,這有助于我們更好地理解和使用Elasticsearch。
Elasticsearch基本概念
全文搜索(Full-text Search)
??全文檢索是指計算機索引程序通過掃描文章中的每一個詞,對每一個詞建立一個索引,指明該詞在文章中出現(xiàn)的次數(shù)和位置,當用戶查詢時,檢索程序就根據(jù)事先建立的索引進行查找,并將查找的結果反饋給用戶的檢索方式。
??在全文搜索的世界中,存在著幾個龐大的帝國,也就是主流工具,主要有:
- Apache Lucene
- Elasticsearch
- Solr
- Ferret
倒排索引(Inverted Index)
??該索引表中的每一項都包括一個屬性值和具有該屬性值的各記錄的地址。由于不是由記錄來確定屬性值,而是由屬性值來確定記錄的位置,因而稱為倒排索引(inverted index)。Elasticsearch能夠實現(xiàn)快速、高效的搜索功能,正是基于倒排索引原理。
節(jié)點 & 集群(Node & Cluster)
??Elasticsearch 本質上是一個分布式數(shù)據(jù)庫,允許多臺服務器協(xié)同工作,每臺服務器可以運行多個Elasticsearch實例。單個Elasticsearch實例稱為一個節(jié)點(Node),一組節(jié)點構成一個集群(Cluster)。
索引(Index)
??Elasticsearch 數(shù)據(jù)管理的頂層單位就叫做 Index(索引),相當于關系型數(shù)據(jù)庫里的數(shù)據(jù)庫的概念。另外,每個Index的名字必須是小寫。
文檔(Document)
??Index里面單條的記錄稱為 Document(文檔)。許多條 Document 構成了一個 Index。Document 使用 JSON 格式表示。同一個 Index 里面的 Document,不要求有相同的結構(scheme),但是最好保持相同,這樣有利于提高搜索效率。
類型(Type)
??Document 可以分組,比如employee這個 Index 里面,可以按部門分組,也可以按職級分組。這種分組就叫做 Type,它是虛擬的邏輯分組,用來過濾 Document,類似關系型數(shù)據(jù)庫中的數(shù)據(jù)表。
??不同的 Type 應該有相似的結構(Schema),性質完全不同的數(shù)據(jù)(比如 products 和 logs)應該存成兩個 Index,而不是一個 Index 里面的兩個 Type(雖然可以做到)。
文檔元數(shù)據(jù)(Document metadata)
??文檔元數(shù)據(jù)為_index, _type, _id, 這三者可以唯一表示一個文檔,_index表示文檔在哪存放,_type表示文檔的對象類別,_id為文檔的唯一標識。
字段(Fields)
??每個Document都類似一個JSON結構,它包含了許多字段,每個字段都有其對應的值,多個字段組成了一個 Document,可以類比關系型數(shù)據(jù)庫數(shù)據(jù)表中的字段。
??在 Elasticsearch 中,文檔(Document)歸屬于一種類型(Type),而這些類型存在于索引(Index)中,下圖展示了Elasticsearch與傳統(tǒng)關系型數(shù)據(jù)庫的類比:
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>'
返回的數(shù)據(jù)格式為JSON,因為Elasticsearch中的文檔以JSON格式儲存。其中,被 < >
標記的部件:
部件 | 說明 |
---|---|
VERB | 適當?shù)?HTTP 方法 或 謂詞 : GET 、 POST 、 PUT 、 HEAD 或者 DELETE 。 |
PROTOCOL |
http 或者 https (如果你在 Elasticsearch 前面有一個 https 代理) |
HOST | Elasticsearch 集群中任意節(jié)點的主機名,或者用 localhost 代表本地機器上的節(jié)點。 |
PORT | 運行 Elasticsearch HTTP 服務的端口號,默認是 9200 。 |
PATH | API 的終端路徑(例如 _count 將返回集群中文檔數(shù)量)。Path 可能包含多個組件,例如:_cluster/stats 和 _nodes/stats/jvm 。 |
QUERY_STRING | 任意可選的查詢字符串參數(shù) (例如 ?pretty 將格式化地輸出 JSON 返回值,使其更容易閱讀) |
BODY | 一個 JSON 格式的請求體 (如果請求需要的話) |
對于HTTP方法,它們的具體作用為:
HTTP方法 | 說明 |
---|---|
GET | 獲取請求對象的當前狀態(tài) |
POST | 改變對象的當前狀態(tài) |
PUT | 創(chuàng)建一個對象 |
DELETE | 銷毀對象 |
HEAD | 請求獲取對象的基礎信息 |
??我們以下面的數(shù)據(jù)為例,來展示Elasticsearch的用法。
以下全部的操作都在Kibana中完成,創(chuàng)建的index為conference, type為event .
插入數(shù)據(jù)
??首先創(chuàng)建index為conference, 創(chuàng)建type為event, 插入id為1的第一條數(shù)據(jù),只需運行下面命令就行:
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條數(shù)據(jù),完成插入后,查看數(shù)據(jù)如下:
刪除數(shù)據(jù)
??比如我們想要刪除conference中event里面id為5的數(shù)據(jù),只需運行下面命令即可:
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
修改數(shù)據(jù)
??修改數(shù)據(jù)的命令為POST, 比如我們想要將conference中event里面id為4的文檔的作者改為Bob,那么需要運行命令如下:
POST /conference/event/4/_update
{
"doc": {"host": "Bob"}
}
返回的信息如下:(表示修改數(shù)據(jù)成功)
{
"_index" : "conference",
"_type" : "event",
"_id" : "4",
"_version" : 7,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 7,
"_primary_term" : 1
}
查看修改后的數(shù)據(jù)如下:
查詢數(shù)據(jù)
??查詢數(shù)據(jù)的命令為GET,查詢命令也是Elasticsearch最為重要的功能之一。比如我們想查詢conference中event里面id為1的數(shù)據(jù),運行命令如下:
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
返回結果包括了所有四個文檔,放在數(shù)組 hits 中。
??當然,Elasticsearch 提供更加豐富靈活的查詢語言叫做 查詢表達式 , 它支持構建更加復雜和健壯的查詢。利用查詢表達式,我們可以檢索出conference中event里面所有host為Bob的文檔,命令如下:
GET /conference/event/_search
{
"query" : {
"match" : {
"host" : "Bob"
}
}
}
返回的結果只包括了一個文檔,放在數(shù)組 hits 中。
??接著,讓我們嘗試稍微高級點兒的全文搜索——一項傳統(tǒng)數(shù)據(jù)庫確實很難搞定的任務。搜索下所有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",
...
}
}
]
}
}
返回的結果包含了兩個文檔,放在數(shù)組 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還支持更多的搜索功能,比如過濾器,高亮搜索,結構化搜索等,希望接下來能有更多的時間和經歷來介紹~
總結
??后續(xù)有機會再介紹如何利用Python來操作Elasticsearch~
??本次分享到此結束,感謝大家閱讀~
注意:本人現(xiàn)已開通微信公眾號: Python爬蟲與算法(微信號為:easy_web_scrape), 歡迎大家關注哦~~