天天看點

ElasticSearch系列(二):基本資料操作(上)

作者:paulpei

一. 前期知識及環境準備

在正式學習ES的基本資料操作之前,需要了解一下以下相關的基本概念:

  1. 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工作正常

ElasticSearch系列(二):基本資料操作(上)

5.Kibana 檢查

通路Kibana:http://192.168.246.134:5601

顯示界面如下:

ElasticSearch系列(二):基本資料操作(上)

點選【Explore on my own】

ElasticSearch系列(二):基本資料操作(上)

點選左上角的菜單,選擇【Management】下的【Dev Tools】,進入如下界面,之後的例子也将在此功能裡面執行,并顯示輸出結果。

輸入 如下: GET /

點選該行右邊的箭頭 ,發送請求,則在右邊的顯示區域會顯示請求結果資訊,如下圖所示:

ElasticSearch系列(二):基本資料操作(上)

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

二.建立索引及文檔

  1. 建立索引及文檔

使用PUT方法來進行建立索引及文檔

注: 以下所有 # 的部分,僅僅為了注釋說明,執行的時候,請去掉,否則會報告錯誤。

例如:

PUT ddz/_doc/1 # 索引名:ddz 文檔id:1

{

"uid":10001, # 文檔字段:值

"nickname":"麥子",

"coin":3000,

"phone":13622445609,

"score":203

}

ElasticSearch系列(二):基本資料操作(上)

右邊輸出資訊如下:

#! 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資訊如下:

ElasticSearch系列(二):基本資料操作(上)

2.建立立即用于搜尋的索引及文檔

一般情況下,新寫入的文檔并不能馬上被用于搜尋,索引必須寫入到 Segment 後才能被搜尋到,需要等到 refresh 操作才可以。而在預設的情況下,refresh 一次的時間間隔是一秒。這也是通常所說的 Elasticsearch 可以實作秒級的搜尋的由來。但,如果指定了強制 refresh 操作,則可以馬上被用于搜尋。

例如:

PUT ddz/_doc/2?refresh=true

{

"uid":10002,

"nickname":"鴿子",

"coin":34000,

"phone":17022448601,

"score":-33

}

ElasticSearch系列(二):基本資料操作(上)

右邊輸出資訊如下:

{

"_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

}

ElasticSearch系列(二):基本資料操作(上)

右邊輸出資訊如下:

{

"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

ElasticSearch系列(二):基本資料操作(上)

如果可以查找到索引資訊,右邊的輸出資訊,則顯示查找到的索引資訊。

{

"_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系列(二):基本資料操作(中)】

繼續閱讀