# 啟程
為了能讓你感受一下 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" ]
}
~~~