一. 前期知識及環境準備
在正式學習ES的基本資料操作之前,需要了解一下以下相關的基本概念:
- JSON
JSON(JavaScript Object Notation)是一種輕量級的資料交換格式。它基于 ECMAScript(European Computer Manufacturers Association, 歐洲計算機協會制定的js規範)的一個子集,采用完全獨立于程式設計語言的文本格式來存儲和表示資料。簡潔和清晰的層次結構使得 JSON 成為理想的資料交換語言。 易于人閱讀和編寫,同時也易于機器解析和生成。在 Elasticsearch 中,是以的資料都是以 JSON 的格式來進行表述的。
2.REST
REST 即表述性狀态傳遞(Representational State Transfer,簡稱 REST)是 Roy Fielding 博士在2000年他的博士論文中提出來的一種軟體架構風格。REST 是一種規範。即參數通過封裝後進行傳遞,響應也是傳回的一個封裝對象。
可以通過使用 REST 接口來對 Elasticsearch 進行操作,對資料進行增加(Create),查詢(Read),更新(Update)及删除(Delete),也就是通常說的 CRUD。
Elasticsearch 裡的接口都是通過 REST 接口來實作的。
方法 | 用法 |
GET | 讀取資料 |
POST | 插入資料 |
PUT | 更新資料,或如果是一個新的 id,則插入資料 |
DELETE | 删除資料 |
3.curl
可以使用 curl 将請求從指令行送出到本地 Elasticsearch 執行個體。對 Elasticsearch 的請求包含與任何 HTTP 請求相同的部分:
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
使用以下變量:
<VERB> :适當的 HTTP 方法或動詞。 例如,GET,POST,PUT,HEAD 或 DELETE
<PROTOCOL>:http 或 https。 如果你在 Elasticsearch 前面有一個 HTTPS 代理,或者你使用 Elasticsearch 安全功能來加密 HTTP 通信,請使用後者
<HOST>:Elasticsearch 叢集中任何節點的主機名。 localhost 用于本地計算機上的節點
<PORT>:運作 Elasticsearch HTTP 服務的端口,預設為9200
<PATH>:API 端點,可以包含多個元件,例如 _cluster/stats 或 _nodes/stats/jvm
<QUERY_STRING>:任何可選的查詢字元串參數。 例如,?pretty 将漂亮地列印 JSON 響應以使其更易于閱讀
<BODY>:JSON 編碼的請求正文(如有必要)
如果啟用了 Elasticsearch 安全功能,則還必須提供有權運作 API 的有效使用者名(和密碼)。 例如,使用 -u 或 --u cURL 指令參數。比如:
curl -u elastic:password -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
4.Elasticsearch 檢查
通路Elasticsearch :http://192.168.246.134:9200/
傳回如下資訊,證明Elasticsearch工作正常
5.Kibana 檢查
通路Kibana:http://192.168.246.134:5601
顯示界面如下:
點選【Explore on my own】
點選左上角的菜單,選擇【Management】下的【Dev Tools】,進入如下界面,之後的例子也将在此功能裡面執行,并顯示輸出結果。
輸入 如下: GET /
點選該行右邊的箭頭 ,發送請求,則在右邊的顯示區域會顯示請求結果資訊,如下圖所示:
GET /
和
http://192.168.246.134:9200/ 看到的資訊一緻。
6.Elasticsearch資料類型
ES的資料類型比較多,請見下表:
Types | 資料類型 | 資料類型 |
Common Types | binary | binary |
boolean | boolean | |
Keywords | keyword | |
constant_keyword | ||
wildcard | ||
Numbers | long | |
integer | ||
short | ||
byte | ||
double | ||
float | ||
half_float | ||
scaled_float | ||
unsigned_long | ||
Dates | date | |
date_nanos | ||
alias | alias | |
Objects and relational | object | |
flattened | flattened | |
nested | nested | |
join | join | |
Structured | Range | long_range |
integer_range | ||
float_range | ||
double_range | ||
date_range | ||
ip_range | ||
ip | ip | |
version | version | |
Aggregate | aggregate_metric_double | aggregate_metric_double |
histogram | histogram | |
Text search | text | text |
match_only_text | ||
completion | completion | |
search_as_you_type | search_as_you_type | |
token_count | token_count | |
Document ranking | dense_vector | dense_vector |
sparse_vector | sparse_vector | |
rank_feature | rank_feature | |
rank_features | rank_features | |
Spatial | geo_point | geo_point |
geo_shape | geo_shape | |
point | point | |
shape | shape | |
Other | percolator | percolator |
每一種資料類型的應用,後續章節會逐漸涉及,這裡僅僅先做個大概了解。
具體請參見:
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/mapping-types.html
二.建立索引及文檔
- 建立索引及文檔
使用PUT方法來進行建立索引及文檔
注: 以下所有 # 的部分,僅僅為了注釋說明,執行的時候,請去掉,否則會報告錯誤。
例如:
PUT ddz/_doc/1 # 索引名:ddz 文檔id:1
{
"uid":10001, # 文檔字段:值
"nickname":"麥子",
"coin":3000,
"phone":13622445609,
"score":203
}
右邊輸出資訊如下:
#! Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html to enable security.
注:因未開啟安全認證,是以會有如下的提示資訊,暫時忽略此資訊。
{
"_index" : "ddz", # 索引名
"_type" : "_doc", # Type名
"_id" : "1", # ID
"_version" : 2, # 版本,資料更改一次,此值會自動增加1,此處為了示範,執行了2次
"result" : "updated", # 更新
"_shards" : {
"total" : 2, # 兩個shards,一個是Primary,另一個是Replica
"successful" : 1, # 成功
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
以上例子,建立了一個新的索引及文檔,在此例中,并未事先确定字段的資料類型,但Elasticsearch 會根據所輸入字段的資料自動猜測它的資料類型,比如上面的 nickname被認為是 text 類型,而coin将被猜測為long類型。這種方式稱之為 schema on write。
在 Elasticsearch 的術語中,mapping 被稱作為 Elasticsearch 的資料 schema。文檔中的所有字段都需要映射到 Elasticsearch 中的資料類型。 mapping 指定每個字段的資料類型,并确定應如何索引和分析字段以進行搜尋。 在 SQL 資料庫中定義表時,mapping 類似于 schema。
執行:GET ddz/_mapping 可以檢視mapping資訊如下:
2.建立立即用于搜尋的索引及文檔
一般情況下,新寫入的文檔并不能馬上被用于搜尋,索引必須寫入到 Segment 後才能被搜尋到,需要等到 refresh 操作才可以。而在預設的情況下,refresh 一次的時間間隔是一秒。這也是通常所說的 Elasticsearch 可以實作秒級的搜尋的由來。但,如果指定了強制 refresh 操作,則可以馬上被用于搜尋。
例如:
PUT ddz/_doc/2?refresh=true
{
"uid":10002,
"nickname":"鴿子",
"coin":34000,
"phone":17022448601,
"score":-33
}
右邊輸出資訊如下:
{
"_index" : "ddz",
"_type" : "_doc",
"_id" : "2",
"_version" : 1, # 版本為1
"result" : "created", # 建立
"forced_refresh" : true, # 強制重新整理
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
3.同步建立索引及文檔
上面的方式可以強制使 Elasticsearch 進行 refresh 的操作,但是頻繁的進行這種操作,可以使我們的 Elasticsearch 變得非常慢,顯然,這不是所期望的。
故此,也提供了另外一種同步的方式,通過設定 refresh=wait_for,等待下一個 refresh 周期發生完後,才傳回。這樣可以確定在調用上面的接口後,馬上可以搜尋到剛才錄入的文檔:
例如:
PUT ddz/_doc/3?refresh=wait_for
{
"uid":10003,
"nickname":"栗子",
"coin":31000,
"phone":17122359451,
"score":562
}
4.建立索引及文檔
一般來說,在寫入文檔時,如果該文檔的 ID 已經存在,那麼就會更新現有的文檔;如果該文檔從來沒有存在過,那麼就建立新的文檔。如果,這不是所期望的處理方式,而是,期望存在的時候,再次寫入,可以報告錯誤,則可以借助 _create 端點接口實作。
例如:
PUT ddz/_create/1
{
"uid":10001,
"nickname":"麥子",
"coin":3000,
"phone":13622445609,
"score":203
}
右邊輸出資訊如下:
{
"error" : {
"root_cause" : [
{
"type" : "version_conflict_engine_exception",
"reason" : "[1]: version conflict, document already exists (current version [2])",
"index_uuid" : "0PgbkAV8RYumrBDA268xxw",
"shard" : "0",
"index" : "ddz"
}
],
"type" : "version_conflict_engine_exception",
"reason" : "[1]: version conflict, document already exists (current version [2])",
"index_uuid" : "0PgbkAV8RYumrBDA268xxw",
"shard" : "0",
"index" : "ddz"
},
"status" : 409
}
下面指令效果和上面相同
PUT ddz/_doc/1?op_type=create
{
"uid":10001,
"nickname":"麥子",
"coin":3000,
"phone":13622445609,
"score":203
}
5.查找文檔:
上面的例子建立了索引文檔,需要查找,驗證是否正确。可以借助GET方法實作。
執行:
GET ddz/_doc/1
如果可以查找到索引資訊,右邊的輸出資訊,則顯示查找到的索引資訊。
{
"_index" : "ddz",
"_type" : "_doc",
"_id" : "1",
"_version" : 3,
"_seq_no" : 5,
"_primary_term" : 1,
"found" : true, # 标記為true,找到
"_source" : {
"uid" : 10001,
"nickname" : "麥子",
"coin" : 3000,
"phone" : 13622445609,
"score" : 203
}
}
反之,如果查不到索引資訊,輸出資訊如下:
{
"_index" : "ddz",
"_type" : "_doc",
"_id" : "13",
"found" : false # 标記為false,未找到
}
後續見【ElasticSearch系列(二):基本資料操作(中)】