1.1 初識
Elasticsearch 是一個建立在全文搜索引擎 Apache Lucene(TM) 基礎上的搜索引擎,可以說 Lucene 是當今最先進,最高效的全功能開源搜索引擎框架。
但是 Lucene 只是一個框架,要充分利用它的功能,你需要使用 JAVA,並且在你的程序中集成 Lucene。更糟的是,你需要做很多的學習了解,才能明白它是如何運行的,Lucene 確實非常復雜。
Elasticsearch 使用 Lucene 作為內部引擎,但是在你使用它做全文搜索時,只需要使用統一開發好的API即可,而並不需要了解其背后復雜的 Lucene 的運行原理。
當然 Elasticsearch 並不僅僅是 Lucene 那么簡單,它不僅包括了全文搜索功能,還可以進行以下工作:
-
- 分布式實時文件存儲,並將每一個字段都編入索引,使其可以被搜索。
- 實時分析的分布式搜索引擎。
- 可以擴展到上百台服務器,處理PB級別的結構化或非結構化數據。
這么多的功能被集成到一台服務器上,你可以輕松地通過客戶端或者任何你喜歡的程序語言與 ES 的 RESTful API 進行交流。
Elasticsearch 的上手是非常簡單的。它附帶了很多非常合理的默認值,這讓初學者很好地避免一上手就要面對復雜的理論,它安裝好了就可以使用了,用很小的學習成本就可以變得很有生產力。
隨着學習的深入,你還可以使用 Elasticsearch 更多高級的功能,整個引擎可以很靈活地進行配置。你可以根據自身需求來定制屬於你自己的 Elasticsearch。
1.2 安裝
安裝 JAVA
yum install java-1.7.0-openjdk -y
安裝 Elasticsearch
了解 Elasticsearch 最簡單的方法就是去盡情的玩兒它(汗),准備好了我們就開始吧。
安裝 Elasticsearch 只有一個要求,就是要安裝最新版本的JAVA。你可以到官方網站下載它:www.java.com.
你可以在這里下載到最新版本的 Elasticsearch: elasticsearch.org/download.
curl -L -O http://download.elasticsearch.org/PATH/TO/LATEST/$VERSION.zip unzip elasticsearch-$VERSION.zip cd elasticsearch-$VERSION
提示: 當你安裝 Elasticsearch 時,你可以到 下載頁面 選擇Debian或者RP安裝包。或者你也可以使用官方提供的 Puppet module 或者 Chef cookbook.
安裝 Marvel
這是個付費的監控插件 暫時先不翻譯
Marvel is a management and monitoring tool for Elasticsearch which is free for development use. It comes with an interactive console called Sense which makes it very easy to talk to Elasticsearch directly from your browser.
Many of the code examples in this book include a ``View in Sense'' link. When clicked, it will open up a working example of the code in the Sense console. You do not have to install Marvel, but it will make this book much more interactive by allowing you to experiment with the code samples on your local Elasticsearch cluster.
Marvel is available as a plugin. To download and install it, run this command in the Elasticsearch directory:
./bin/plugin -i elasticsearch/marvel/latest
You probably don't want Marvel to monitor your local cluster, so you can disable data collection with this command:
echo 'marvel.agent.enabled: false' >> ./config/elasticsearch.yml
運行 Elasticsearch
Elasticsearch 已經蓄勢待發,現在你便可以運行它了:
./bin/elasticsearch
如果你想讓它在后台保持運行的話可以在命令后面再加一個 -d
開啟后你就可以使用另一個終端窗口來進行測試了:
curl 'http://localhost:9200/?pretty'
你應該看到如下提示:
{
"status": 200, "name": "Shrunken Bones", "version": { "number": "1.4.0", "lucene_version": "4.10" }, "tagline": "You Know, for Search" }
這就說明你的 Elasticsearch 集群 已經上線運行了,這時我們就可以進行各種實驗了。
集群和節點
節點 是 Elasticsearch 運行的實例。集群 是一組有着同樣cluster.name
的節點,它們協同工作,互相分享數據,提供了故障轉移和擴展的功能。當然一個節點也可以是一個集群。
1.3 API
與 Elasticsearch 通信
如何與 Elasticsearch 通信要取決於你是否使用 JAVA。
Java API
如果你使用的是 JAVA,Elasticsearch 內置了兩個客戶端,你可以在你的代碼中使用:
節點客戶端: 節點客戶端以一個 無數據節點 的身份加入了一個集群。換句話說,它自身是沒有任何數據的,但是他知道什么數據在集群中的哪一個節點上,然后就可以請求轉發到正確的節點上並進行連接。
傳輸客戶端: 更加輕量的傳輸客戶端可以被用來向遠程集群發送請求。他並不加入集群本身,而是把請求轉發到集群中的節點。
這兩個客戶端都使用 Elasticsearch 的 傳輸 協議,通過9300端口與 java 客戶端進行通信。集群中的各個節點也是通過9300端口進行通信。如果這個端口被禁止了,那么你的節點們將不能組成一個集群。
TIP
Java 的客戶端的版本號必須要與 Elasticsearch 節點所用的版本號一樣,不然他們之間可能無法識別。
更多關於 Java API 的說明可以在這里找到 Guide.
通過 HTTP 向 RESTful API 傳送 json
其他的語言可以通過9200端口與 Elasticsearch 的 RESTful API 進行通信。事實上,如你所見,你甚至可以使用行命令 curl
來與 Elasticsearch 通信。
Elasticsearch 官方提供了很多種編程語言的客戶端,也有和許多社區化軟件的集成插件,這些都可以在Guide 里面找到。
向 Elasticsearch 發出的請求和其他所有的 HTTP 請求的組成部分是一致的。例如,計算集群中文件的數量,我們就可以使用:
<1> <2> <3> <4> curl -XGET 'http://localhost:9200/_count?pretty' -d ' { <5> "query": { "match_all": {} } } '
-
-
相應的 HTTP 請求方法 或者 變量 :
GET
,POST
,PUT
,HEAD
或者DELETE
。 -
集群中任意一個節點的訪問協議、主機名以及端口。
-
請求的路徑。
-
任意一個查詢后再加上
?pretty
就可以生成 更加美觀 的JSON反饋,以增強可讀性。 -
一個 JSON 編碼的請求主體(如果需要的話)。
-
Elasticsearch 將會返回一個 HTTP 狀態碼類似於 '200 OK',以及一個 JSON 格式的主體(除了單純的 'HEAD' 請求),上面的請求會得到下方的 JSON 主體:
{ "count" : 0, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 } }
在反饋中,我們並沒有看見 HTTP 的頭部信息,因為我們沒有告知 curl
顯示這些內容。如果你想看到頭部信息,可以在使用 curl
命令的時候再加上 -i
這個參數:
curl -i -XGET 'localhost:9200/'
從現在開始,本書里所有涉及 curl
命令的部分我們都會進行簡寫,因為主機、端口等信息都是相同的,縮減前的樣子:
curl -XGET 'localhost:9200/_count?pretty' -d ' { "query": { "match_all": {} } }'
我們將會簡寫成這樣:
GET /_count { "query": { "match_all": {} } }
1.4 文檔
面向文檔
程序中的對象很少是單純的鍵值與數值的列表。更多的時候它擁有一個復雜的結構,比如包含了日期、地理位置、對象、數組等。
遲早你會把這些對象存儲在數據庫中。你會試圖將這些豐富而又龐大的數據都放到一個由行與列組成的關系數據庫中,然后你不得不根據每個字段的格式來調整數據,然后每次重建它你都要檢索一遍數據。
Elasticsearch 是 面向文檔型數據庫,這意味着它存儲的是整個對象或者 文檔,它不但會存儲它們,還會為他們建立索引,這樣你就可以搜索他們了。你可以在 Elasticsearch 中索引、搜索、排序和過濾這些文檔。不需要成行成列的數據。這將會是完全不同的一種面對數據的思考方式,這也是為什么 Elasticsearch 可以執行復雜的全文搜索的原因。
JSON
Elasticsearch使用 JSON (或稱作JavaScript Object Notation ) 作為文檔序列化的格式。JSON 已經被大多數語言支持,也成為 NoSQL 領域的一個標准格式。它簡單、簡潔、易於閱讀。
把這個 JSON 想象成一個用戶對象:
{
"email": "john@smith.com", "first_name": "John", "last_name": "Smith", "about": { "bio": "Eco-warrior and defender of the weak", "age": 25, "interests": [ "dolphins", "whales" ] }, "join_date": "2014/05/01", }
雖然 user
這個對象非常復雜,但是它的結構和含義都被保留到 JSON 中了。在 Elasticsearch 中,將對象轉換為 JSON 並作為索引要比在表結構中做相同的事情簡單多了。
將你的數據轉換為 JSON
幾乎所有的語言都有將任意數據轉換、機構化成 JSON,或者將對象轉換為JSON的模塊。查看 serialization
以及marshalling
兩個 JSON 模塊。The official Elasticsearch clients 也可以幫你自動結構化 JSON。
1.5 索引
啟程
為了能讓你感受一下 Elasticsearch 能做什么以及它是有多么的易用,我們會先為你簡單展示一下,其中包括了基本的 創建索引,搜索 以及 聚合。
我們會在這里向你介紹一些新的術語以及簡單的概念,即使你沒有馬上接受這些概念也沒有關系。我們會在之后的章節中逐漸幫你理解它們。
所以,准備開始享受 Elasticsearch 的學習之旅把!
建立一個員工名單
想象我們正在為一個名叫 megacorp 的公司的 HR 部門制作一個新的員工名單系統,這些名單應該可以滿足實時協同工作,所以它應該可以滿足以下要求:
-
- 數據可以包含多個值的標簽、數字以及純文本內容,
- 可以檢索任何職員的所有數據。
- 允許結構化搜索。例如,查找30歲以上的員工。
- 允許簡單的全文搜索以及相對復雜的短語搜索。
- 在返回的匹配文檔中高亮關鍵字。
- 擁有數據統計與管理的后台。
為員工檔案創建索引
這個項目的第一步就是存儲員工的數據。這樣你就需要一個“員工檔案”的表單,這樣每個文檔都代表着一個員工。在 Elasticsearch 中,存儲數據的行為就叫做 索引(indexing) ,但是在我們索引數據前,我們需要決定將數據存儲在哪里。
在 Elasticsearch 中,文檔屬於一種 類型(type),各種各樣的類型存在於一個 索引 中。你也可以通過類比傳統的關系數據庫得到一些大致的相似之處:
關系數據庫 ⇒ 數據庫 ⇒ 表 ⇒ 行 ⇒ 列(Columns)
Elasticsearch ⇒ 索引 ⇒ 類型 ⇒ 文檔 ⇒ 字段(Fields)
一個 Elasticsearch 集群可以包含多個 索引(數據庫),也就是說其中包含了很多 類型(表)。這些類型中包含了很多的 文檔(行),然后每個文檔中又包含了很多的 字段(列)。
索引 索引 索引
你可能發現在 Elasticsearch 中,索引這個詞匯已經被賦予了太多意義,所以在這里我們有必要澄清一下:
索引 (名詞)
如上文所說,一個 索引 就類似於傳統關系型數據庫中的 數據庫。這里就是存儲相關文檔的的地方。
索引 (動詞)
為一個文檔創建索引 是把一個文檔存儲到一個索引(名詞)中的過程,這樣它才能被檢索。這個過程非常類似於 SQL 中的 INSERT
命令,如果已經存在文檔,新的文檔將會覆蓋舊的文檔。
反向索引
在關系數據庫中的某列添加一個 索引,比如多路搜索樹(B-Tree)索引,就可以加速數據的取回速度, Elasticsearch 以及 Lucene 使用的是一個叫做 反向索引(inverted index) 的結構來實現相同的功能。
通常,每個文檔中的字段都被創建了索引(擁有一個反向索引),因此他們可以被搜索。如果一個字段缺失了反向索引的話,它將不能被搜索。我們將會在之后的《反向索引》章節中詳細介紹它。
所以為了創建員工名單,我們需要進行如下操作:
-
- 為每一個員工的 文檔 創建索引,每個 文檔 都包含了一個員工的所有信息。
- 每個文檔都會被標記為
employee
類型。 - 這種類型將存活在
megacorp
這個 索引 中。 - 這個索引將會存儲在 Elasticsearch 的集群中
在實際的操作中,這些操作是非常簡單的(即使看起來有這么多步驟)。我們可以把如此之多的操作通過一個命令來完成:
PUT /megacorp/employee/1 { "first_name" : "John", "last_name" : "Smith", "age" : 25, "about" : "I love to go rock climbing", "interests": [ "sports", "music" ] }
注意在 /megacorp/employee/1
路徑下,包含了三個部分:
名字 | 內容 |
---|---|
megacorp | 索引的名字 |
employee | 類型的名字 |
1 | 當前員工的ID |
請求部分,也就是 JSON 文檔,在這里包含了關於這名員工的所有信息。他的名字是 “John Smith”,他已經25歲了,他很喜歡攀岩。
怎么樣?很簡單吧!我們在操作前不需要進行任何管理操作,比如創建索引,或者為字段指定數據的類型。我們就這么直接地為一個文檔創建了索引。Elasticsearch 會在創建的時候為它們設定默認值,所以所有管理操作已經在后台被默默地完成了。
在進行下一步之前,我們再為這個目錄添加更多的員工信息吧:
PUT /megacorp/employee/2 { "first_name" : "Jane", "last_name" : "Smith", "age" : 32, "about" : "I like to collect rock albums", "interests": [ "music" ] } PUT /megacorp/employee/3 { "first_name" : "Douglas", "last_name" : "Fir", "age" : 35, "about": "I like to build cabinets", "interests": [ "forestry" ] }
1.6 搜索
檢索文檔
現在,我們已經在 Elasticsearch 中存儲了一些數據,我們可以開始根據這個項目的需求進行工作了。第一個需求就是要能搜索每一個員工的數據。
對於 Elasticsearch 來說,這是非常簡單的。我們只需要執行一次 HTTP GET 請求,然后指出文檔的地址,也就是索引、類型以及 ID 即可。通過這三個部分,我們就可以得到原始的 JSON 文檔:
GET /megacorp/employee/1
返回的內容包含了這個文檔的元數據信息,而 John Smith 的原始 JSON 文檔也在 _source
字段中出現了:
{
"_index" : "megacorp", "_type" : "employee", "_id" : "1", "_version" : 1, "found" : true, "_source" : { "first_name" : "John", "last_name" : "Smith", "age" : 25, "about" : "I love to go rock climbing", "interests": [ "sports", "music" ] } }
我們通過將HTTP后的請求方式由 PUT
改變為 GET
來獲取文檔,同理,我們也可以將其更換為 DELETE
來刪除這個文檔,HEAD
是用來查詢這個文檔是否存在的。如果你想替換一個已經存在的文檔,你只需要使用 PUT
再次發出請求即可。
簡易搜索
GET
命令真的相當簡單,你只需要告訴它你要什么即可。接下來,我們來試一下稍微復雜一點的搜索。
我們首先要完成一個最簡單的搜索命令來搜索全部員工:
GET /megacorp/employee/_search
你可以發現我們正在使用 megacorp
索引,employee
類型,但是我們我們並沒有指定文檔的ID,我們現在使用的是 _search
端口。你可以再返回的 hits
中發現我們錄入的三個文檔。搜索會默認返回最前的10個數值。
{
"took": 6, "timed_out": false, "_shards": { ... }, "hits": { "total": 3, "max_score": 1, "hits": [ { "_index": "megacorp", "_type": "employee", "_id": "3", "_score": 1, "_source": { "first_name": "Douglas", "last_name": "Fir", "age": 35, "about": "I like to build cabinets", "interests": [ "forestry" ] } }, { "_index": "megacorp", "_type": "employee", "_id": "1", "_score": 1, "_source": { "first_name": "John", "last_name": "Smith", "age": 25, "about": "I love to go rock climbing", "interests": [ "sports", "music" ] } }, { "_index": "megacorp", "_type": "employee", "_id": "2", "_score": 1, "_source": { "first_name": "Jane", "last_name": "Smith", "age": 32, "about": "I like to collect rock albums", "interests": [ "music" ] } } ] } }
注意:反饋值中不僅會告訴你匹配到哪些文檔,同時也會把這個文檔都會包含到其中:我們需要搜索的用戶的所有信息。
接下來,我們將要嘗試着實現搜索一下哪些員工的姓氏中包含 Smith
。為了實現這個,我們需要使用一種輕量的搜索方法。這種方法經常被稱做 查詢字符串(query string) 搜索,因為我們通過URL來傳遞查詢的關鍵字:
GET /megacorp/employee/_search?q=last_name:Smith
我們依舊使用 _search
端口,然后可以將參數傳入給 q=
。這樣我們就可以得到姓Smith的結果:
{
...
"hits": { "total": 2, "max_score": 0.30685282, "hits": [ { ... "_source": { "first_name": "John", "last_name": "Smith", "age": 25, "about": "I love to go rock climbing", "interests": [ "sports", "music" ] } }, { ... "_source": { "first_name": "Jane", "last_name": "Smith", "age": 32, "about": "I like to collect rock albums", "interests": [ "music" ] } } ] } }
使用Query DSL搜索
查詢字符串是通過命令語句完成 點對點(ad hoc) 的搜索,但是這也有它的局限性(可參閱《搜索局限性》章節)。Elasticsearch 提供了更加豐富靈活的查詢語言,它被稱作 Query DSL,通過它你可以完成更加復雜、強大的搜索任務。
DSL (Domain Specific Language 領域特定語言) 需要使用 JSON 作為主體,我們還可以這樣查詢姓 Smith 的員工:
GET /megacorp/employee/_search
{
"query" : { "match" : { "last_name" : "Smith" } } }
這個請求會返回同樣的結果。你會發現我們在這里沒有使用 查詢字符串,而是使用了一個由 JSON 構成的請求體,其中使用了 match
查詢法,隨后我們還將會學習到其他的查詢類型。
更加復雜的搜索
接下來,我們再提高一點兒搜索的難度。我們依舊要尋找出姓 Smith 的員工,但是我們還將添加一個年齡大於30歲的限定條件。我們的查詢語句將會有一些細微的調整來以識別結構化搜索的限定條件 filter(過濾器):
GET /megacorp/employee/_search
{
"query" : { "filtered" : { "filter" : { "range" : { "age" : { "gt" : 30 } <1> } }, "query" : { "match" : { "last_name" : "Smith" <2> } } } } }
-
-
這一部分的語句是
range
filter ,它可以查詢所有超過30歲的數據 --gt
代表 greater than (大於)。 -
這一部分我們前一個操作的
match
query 是一樣的
-
先不要被這么多的語句嚇到,我們將會在之后帶你逐漸了解他們的用法。你現在只需要知道我們添加了一個filter,可以在 match
的搜索基礎上再來實現區間搜索。現在,我們的只會顯示32歲的名為Jane Smith的員工了:
{
...
"hits": { "total": 1, "max_score": 0.30685282, "hits": [ { ... "_source": { "first_name": "Jane", "last_name": "Smith", "age": 32, "about": "I like to collect rock albums", "interests": [ "music" ] } } ] } }
全文搜索
上面的搜索都很簡單:名字搜索、通過年齡過濾。接下來我們來學習一下更加復雜的搜索,全文搜索——一項在傳統數據庫很難實現的功能。 我們將會搜索所有喜歡 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, <1> "_source": { "first_name": "John", "last_name": "Smith", "age": 25, "about": "I love to go rock climbing", "interests": [ "sports", "music" ] } }, { ... "_score": 0.016878016, <1> "_source": { "first_name": "Jane", "last_name": "Smith", "age": 32, "about": "I like to collect rock albums", "interests": [ "music" ] } } ] } }
-
- 相關評分
通常情況下,Elasticsearch 會通過相關性來排列順序,第一個結果中,John Smith 的 about
字段中明確地寫到 rock climbing。而在 Jane Smith 的 about
字段中,提及到了 rock,但是並沒有提及到 climbing,所以后者的 _score
就要比前者的低。
這個例子很好地解釋了 Elasticsearch 是如何執行全文搜索的。對於 Elasticsearch 來說,相關性的概念是很重要的,而這也是它與傳統數據庫在返回匹配數據時最大的不同之處。
段落搜索
能夠找出每個字段中的獨立單詞固然很好,但是有的時候你可能還需要去匹配精確的短語或者 段落。例如,我們只需要查詢到 about
字段只包含 rock climbing 的短語的員工。
為了實現這個效果,我們將對 match
查詢變為 match_phrase
查詢:
GET /megacorp/employee/_search
{
"query" : { "match_phrase" : { "about" : "rock climbing" } } }
這樣,系統會沒有異議地返回 John Smith 的文檔:
{
...
"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" ] } } ] } }
高亮我們的搜索
很多程序希望能在搜索結果中 高亮 匹配到的關鍵字來告訴用戶這個文檔是 如何 匹配他們的搜索的。在 Elasticsearch 中找到高亮片段是非常容易的。
讓我們回到之前的查詢,但是添加一個 highlight
參數:
GET /megacorp/employee/_search
{
"query" : { "match_phrase" : { "about" : "rock climbing" } }, "highlight": { "fields" : { "about" : {} } } }
當我們運行這個查詢后,相同的命中結果會被返回,但是我們會得到一個新的名叫 highlight
的部分。在這里包含了 about
字段中的匹配單詞,並且會被 <em></em>
HTML字符包裹住:
{
...
"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>" <1> ] } } ] } }
-
- 在原有文本中高亮關鍵字。
1.7 匯總
統計
最后,我們還有一個需求需要完成:可以讓老板在職工目錄中進行統計。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 } ] } } }
我們可以發現有兩個員工喜歡音樂,還有一個喜歡森林,還有一個喜歡運動。這些數據並沒有被預先計算好,它們是在文檔被查詢的同時實時計算得出的。如果你想要查詢姓 Smith 的員工的興趣匯總情況,你就可以執行如下查詢:
GET /megacorp/employee/_search
{
"query": { "match": { "last_name": "smith" } }, "aggs": { "all_interests": { "terms": { "field": "interests" } } } }
這樣,all_interests
的統計結果就只會包含滿足查詢的文檔了:
...
"all_interests": { "buckets": [ { "key": "music", "doc_count": 2 }, { "key": "sports", "doc_count": 1 } ] }
匯總還允許多個層面的統計。比如我們還可以統計每一個興趣下的平均年齡:
GET /megacorp/employee/_search
{
"aggs" : { "all_interests" : { "terms" : { "field" : "interests" }, "aggs" : { "avg_age" : { "avg" : { "field" : "age" } } } } } }
雖然這次返回的匯總結果變得更加復雜了,但是它依舊很容易理解:
...
"all_interests": { "buckets": [ { "key": "music", "doc_count": 2, "avg_age": { "value": 28.5 } }, { "key": "forestry", "doc_count": 1, "avg_age": { "value": 35 } }, { "key": "sports", "doc_count": 1, "avg_age": { "value": 25 } } ] }
在這個豐富的結果中,我們不但可以看到興趣的統計數據,還能針對不同的興趣來分析喜歡這個興趣的平均年齡
。
即使你現在還不能很好地理解語法,但是相信你還是能發現,用這個功能來實現如此復雜的統計工作是這樣的簡單。你的極限取決於你存入了什么樣的數據喲!
1.8 小結
希望上面的幾個小教程可以很好地向你解釋 Elasticsearch 可以實現什么功能。為了保持教程簡短,這里只提及了一些基礎,除此之外還有很多功能,比如建議、地理定位、過濾、模糊以及部分匹配等。但是相信你也發現了,在這里你只需要很簡單的操作就可以完成復雜的操作。無需配置,添加數據就可以開始搜索!
可能前面有一些語法會讓你覺得很難理解,你可能對如何調整優化它們還有很多疑問。那么,本書之后的章節將會幫助你逐步解開疑問,讓你對 Elasticsearch 是如何工作的有一個全面的了解。
1.9 分布式
分布式特性
在最開始的章節中,我們曾經提到 Elasticsearch 可以被擴展到上百台(甚至上千台)服務器上,來處理PB級別的數據。我們的教程只提及了如何使用它,但是並沒有提及到服務器方面的內容。Elasticsearch 是自動分布的,它在設計時就考慮到可以隱藏分布操作的復雜性。
Elasticsearch 的分布式部分很簡單。你甚至不需要關於分布式系統的任何內容,比如分片、集群、發現等成堆的分布式概念。你可能在你的筆記本中運行着剛才的教程,如果你想在一個擁有100個節點的集群中運行教程,你會發現操作是完全一樣的。
Elasticsearch 很努力地在避免復雜的分布式系統,很多操作都是自動完成的:
-
- 可以將你的文檔分區到不同容器或者 分片 中,這些文檔可能被存在一個節點或者多個節點。
-
- 跨節點平衡集群中節點間的索引與搜索負載。
-
- 自動復制你的數據以提供冗余副本,防止硬件錯誤導致數據丟失。
-
- 自動在節點之間路由,以幫助你找到你想要的數據。
-
- 無縫擴展或者恢復你的集群。
當你在閱讀這本書時,你會發現到有關 Elasticsearch 的分布式特性分布式特性的補充章節。在這些章節中你會了解到如何擴展集群以及故障轉移(《分布式集群》),如何處理文檔存儲(《分布式文檔》),如何執行分布式搜索(《分布式搜索》)
這一部分不是必須要看的——你不懂它們也能正常使用 Elasticsearch。但是幫助你更加全面完整地了解 Elasticsearch。你也可以在之后需要的時候再回來翻閱它們。
1.10 本章總結
到目前為止,你應該已經知道 Elasticsearch 可以實現哪些功能,入門上手是非常簡單的。只需要最少的知識和配置就可以開始使用 Elasticsearch 也是它的追求。學習 Elasticsearch 最好的方法就是開始使用它:進行的檢索與搜索吧!
當然,學得越多,你的生產力就越高。你也就能對特定的內容進行微調,得到更適合你的結果。
之后的章節,我們將會引領你從新手晉級到專家。每一個章節都會解釋一個要點,同時我們也會提供專家級別的小提示。如果你只是剛剛起步,這些提示可能並不是很適合你。Elasticsearch 會在一開始設置很多合理的默認值。你可以在需要提升性能的時候再重新回顧它們。