讀《Elasticsearch 權威指南》基礎入門
Elasticsearch 是一個開源的搜尋引擎,建立在一個全文搜尋引擎庫 Apache Lucene™ 基礎之上。
Elasticsearch 的內部使用 Lucene 做索引與搜尋,但是它的目的是使全文檢索變得簡單, 通過隱藏 Lucene 的複雜性,取而代之的提供一套簡單一致的 RESTful API。然而,Elasticsearch 不僅僅是 Lucene,並且也不僅僅只是一個全文搜尋引擎。
和 Elasticsearch 互動
RESTful API with JSON over HTTP
一個 Elasticsearch 請求和任何 HTTP 請求一樣由若干相同的部件組成:
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
Elasticsearch 返回一個 HTTP 狀態碼和一個 JSON 格式的返回值。
面向文件
Elasticsearch 是面向文件的,意味著它儲存整個物件或文件。Elasticsearch 不僅儲存文件,而且索引每個文件的內容使之可以被檢索。在 Elasticsearch 中,你對文件進行索引、檢索、排序和過濾。
JSON
Elasticsearch 使用 JavaScript Object Notation 或者 JSON 作為文件的序列化格式。
在 Elasticsearch 中將物件轉化為 JSON 並做索引要比在一個扁平的表結構中做相同的事情簡單的多。
索引文件
儲存資料到 Elasticsearch 的行為叫做索引。
一個 Elasticsearch 叢集可以包含多個索引,相應的每個索引可以包含多個型別。這些不同的型別儲存著多個文件,每個文件又有多個屬性。
索引這個詞在 Elasticsearch 語境中包含多重意思:
-
索引(名詞):一個索引類似於傳統關係資料庫中的一個數據庫,是一個儲存關係型文件的地方。
-
索引(動詞):索引一個文件就是儲存一個文件到一個索引(名詞)中,以便它可以被檢索和查詢到。這非常類似於 SQL 語句中的 INSERT 關鍵詞。
-
倒排索引:關係型資料庫通過增加一個索引,比如一個 B 樹(B-tree)索引到指定的列上,以便提升資料檢索速度。Elasticsearch 和 Lucene 使用了一個叫做倒排索引的結構來達到相同的目的。預設的,一個文件中的每一個屬性都是被索引的(有一個倒排索引)和可搜尋的。一個沒有倒排索引的屬性是不能被搜尋到的。
使用查詢表示式搜尋編輯
Elasticsearch 提供一個豐富靈活的查詢語言叫做查詢表示式,它支援構建更加複雜和健壯的查詢。
領域特定語言 (DSL), 指定了使用一個 JSON 請求。
GET /megacorp/employee/_search { "query" : { "match" : { "last_name" : "Smith" } } }
更復雜的搜尋
使用過濾器 filter ,它支援高效地執行一個結構化查詢。
GET /megacorp/employee/_search { "query" : { "bool": { "must": { "match" : { "last_name" : "smith" } }, "filter": { "range" : { "age" : { "gt" : 30 } } } } } }
filter 這部分是一個 range 過濾器,它能找到年齡大於 30 的文件,其中 gt 表示_大於 (_great than)。
全文搜尋
全文搜尋——一項 傳統資料庫確實很難搞定的任務。
搜尋下所有喜歡攀巖(rock climbing)的僱員:
GET /megacorp/employee/_search { "query" : { "match" : { "about" : "rock climbing" } } }
使用 match 查詢在 about 屬性上搜索 “rock climbing” 。
{ ... "hits": { "total":2, "max_score":0.16273327, "hits": [ { ... "_score":0.16273327, "_source": { "first_name":"John", "last_name":"Smith", "age":25, "about":"I love to go rock climbing", "interests": [ "sports", "music" ] } }, { ... "_score":0.016878016, "_source": { "first_name":"Jane", "last_name":"Smith", "age":32, "about":"I like to collect rock albums", "interests": [ "music" ] } } ] } }
_score:相關性得分。
Elasticsearch 預設按照相關性得分排序,即每個文件跟查詢的匹配程度。
Elasticsearch中的相關性概念非常重要,也是完全區別於傳統關係型資料庫的一個概念,資料庫中的一條記錄要麼匹配要麼不匹配。
短語搜尋
精確匹配一系列單詞或者短語。
GET /megacorp/employee/_search { "query" : { "match_phrase" : { "about" : "rock climbing" } } }
返回結果僅有 John Smith 的文件。
高亮搜尋
許多應用都傾向於在每個搜尋結果中 高亮 部分文字片段,以便讓使用者知道為何該文件符合查詢條件。在 Elasticsearch 中檢索出高亮片段也很容易。
再次執行前面的查詢,並增加一個新的 highlight 引數:
GET /megacorp/employee/_search { "query" : { "match_phrase" : { "about" : "rock climbing" } }, "highlight": { "fields" : { "about" : {} } } }
當執行該查詢時,返回結果與之前一樣,與此同時結果中還多了一個叫做 highlight 的部分。這個部分包含了 about 屬性匹配的文字片段,並以 HTML 標籤<em></em>
封裝:
{ ... "hits": { "total":1, "max_score":0.23013961, "hits": [ { ... "_score":0.23013961, "_source": { "first_name":"John", "last_name":"Smith", "age":25, "about":"I love to go rock climbing", "interests": [ "sports", "music" ] }, "highlight": { "about": [ "I love to go <em>rock</em> <em>climbing</em>" ] } } ] } }
分析
Elasticsearch 有一個功能叫聚合(aggregations),允許我們基於資料生成一些精細的分析結果。聚合與 SQL 中的 GROUP BY 類似但更強大。
挖掘出僱員中最受歡迎的興趣愛好:
GET /megacorp/employee/_search { "aggs": { "all_interests": { "terms": { "field": "interests" } } } }
返回結果:
{ ... "hits": { ... }, "aggregations": { "all_interests": { "buckets": [ { "key":"music", "doc_count": 2 }, { "key":"forestry", "doc_count": 1 }, { "key":"sports", "doc_count": 1 } ] } } }
聚合還支援分級彙總。
分散式特性
Elasticsearch 可以橫向擴充套件至數百(甚至數千)的伺服器節點,同時可以處理PB級資料。
Elasticsearch 天生就是分散式的,並且儘可能地遮蔽了分散式系統的複雜性。
-
分配文件到不同的容器或分片中,文件可以儲存在一個或多個節點中
-
按叢集節點來均衡分配這些分片,從而對索引和搜尋過程進行負載均衡
-
將叢集中任一節點的請求路由到存有相關資料的節點
-
叢集擴容時無縫整合新節點,重新分配分片以便從離群節點恢復
Reference:
https://www.elastic.co/guide/cn/elasticsearch/guide/cn/getting-started.html