Elasticsearch筆記1

學習整理自官方文檔

ES與數據庫的對應關係

  • 名詞
ES MYSQL
index(索引) database(數據庫)
type(類型 已廢棄) table(表)
document(文檔) row(行)
field(字段) line(列)

type已於6.0.0之後版本廢棄,一個索引只能有一個類型

  • 遍歷方式

ES有分片的概念,一個大的索引會被分成多個分片來進行存儲數據,使用分佈式的架構對分片進行並行搜索(基於倒排)

傳統數據庫的遍歷,屬於正向全表掃描

  • 索引

ES採用倒排索引,通過把文檔字段分詞,生成一個term index, term dictionary, posting list建立倒排索引

mysql通過B+樹建立正排索引,通過索引正向查詢

  • 事務

ES沒有事務,數據修改,刪除不能回滾

mysql支持事務

  • 數據量

在面對大數據量簡單計算的時候es的效率原高於mysql等傳統數據庫,但是在定位某一個唯一值(如用會員id找會員)時並不需要es
但在大數據的相似計算與查找或簡單計算時,es的分佈式並行計算有絕對的優勢

  • 協議

ES支持http
mysql支持jdbc

環境配置

win10
Elasticsearch 7.0.0
啓動後進入 http://localhost:9200進行測試
在這裏插入圖片描述
Kibana 7.0.0
啓動後進入http://localhost:5601進行測試
在這裏插入圖片描述

查看Elasticsearch信息

GET /
在這裏插入圖片描述

創建索引及文檔

PUT 索引/類型/文檔id
{
  "字段1": "date",
  "字段2": date,
}
  • RDMS中,通常需要有專用的語句來生產相應的數據庫,表格,然後纔可以輸入相應的記錄。但是對於ES,會自動生成對應的index及type。自從Elasticsearch 6.0以後,一個index只能有一個type。如果創建另外一個type的話,系統會告訴我們是錯誤的。執行結果中有一個版本信息,如果這個指定id的document之前沒有被創建過的話,它會顯示爲1。之後如果更改這個document,它的版本會每次自動增加1。
    在這裏插入圖片描述
    每次執行POST或者PUT接口時,如果文檔已經存在,那麼相應的版本就會自動加1,之前的版本拋棄。如果不想直接覆蓋的話,可以使用_create端點接口來實現,如果文檔已經存在的話,會收到一個錯誤的信息.
    在這裏插入圖片描述

  • 在上面當寫入數據時,有意識地把文檔的id在命令中寫了出來。如果不寫這個id的話,ES會自動生產一個id:

在這裏插入圖片描述
看到右邊的一個id像是一個隨機的數值,同時可以看到它的版本信息爲1。
也可以看出來系統所給出來的字段都是以下劃線的形式給出來的,比如:_id, _shards, _index, _typed等。

  • 通常對一個通過上面方法寫入到Elasticsearch的文檔,在默認的情況下並不馬上可以進行搜索。這是因爲在Elasticsearch的設計中,有一個叫做refresh的操作。它可以使更改可見以進行搜索的操作。通常會有一個refresh timer來定時完成這個操作。這個週期爲1秒。這也是通常所說的Elasticsearch可以實現秒級的搜索。當然這個timer的週期也可以在索引的設置中進行配置。如果我們想讓結果馬上可以對搜索可見,可以用如下的方法:
POST twitter/_doc/1?refresh=true
{
  "user": "GB",
  "uid": 1,
  "city": "Beijing",
  "province": "Beijing",
  "country": "China"
}
  • 上面的方式可以強制使Elasticsearch進行refresh的操作,當然這個是有代價的。頻繁的進行這種操作,會使Elasticsearch變得非常慢。另外一種方式是通過設置refresh=wait_for。這樣相當於一個同步的操作,它等待下一個refresh週期發生完後,才返回。這樣可以確保在調用上面的接口後,馬上可以搜索到剛纔錄入的文檔:
POST twitter/_doc/1?refresh=wait_for
{
  "user": "GB",
  "uid": 1,
  "city": "Beijing",
  "province": "Beijing",
  "country": "China"
}

查看文檔

GET 索引/類型/文檔id
在這裏插入圖片描述
如果只對source的內容感興趣的話,可以使用
GET 索引/類型/文檔id/_source
可以直接得到source的信息:在這裏插入圖片描述
也可以只獲取source的部分字段:
GET 索引/類型/文檔id?_source=字段1,字段2...
在這裏插入圖片描述
如果想一次請求查找多個文檔,可以使用_mget接口

在這裏插入圖片描述
也可以只獲得部分字段:
在這裏插入圖片描述
同時請求id爲1和2的兩個文檔,也可以簡單地寫爲:

GET twitter/_doc/_mget
{
  "ids": ["1", "2"]
}

它和上面的做一個是一樣的。使用一個命令同時獲取id爲1及2的文檔。

修改文檔

  • 在上面看到了可以使用POST的命令來修改改一個文檔。通常使用POST來創建一個新的文檔。在使用POST的時候,甚至不用去指定特定的id,系統會幫我們自動生成。但是修改一個文檔時,通常會使用PUT來進行操作,並且,需要指定一個特定的id來進行修改:

在這裏插入圖片描述

  • 使用PUT的這個方法,每次修改一個文檔時,需要把文檔的每一項都要寫出來。這對於有些情況來說並不方便。可以使用POST _update來進行修改:
    在這裏插入圖片描述
  • 在關係數據庫中,通常是對數據庫進行搜索,然後才進行修改。在這種情況下,事先通常並不知道文檔的id,需要通過查詢的方式來進行查詢,然後進行修改。ES也提供了相應的REST接口。

在這裏插入圖片描述
在這裏插入圖片描述
對於那些名字是中文字段的文檔來說,在painless語言中直接打入中文字段名字並不能被認可。可以使用如下的方式來操作:

POST edd/_update_by_query
{
  "query": {
    "match": {
      "姓名": "張彬"
    }
  },
  "script": {
    "source": "ctx._source[\"簽到狀態\"] = params[\"簽到狀態\"]",
    "lang": "painless",
    "params" : {
      "簽到狀態":"已簽到"
    }
  }
}

也可以通過update接口,使用script的方法來進行修改。這個方法也是需要知道文檔的id:
在這裏插入圖片描述

更新文檔

術語“upsert”寬鬆地表示更新或插入,即更新文檔(如果存在),否則,插入新文檔。

僅在文檔事先存在的情況下,在前面的代碼中看到的部分更新纔有效。 如果具有給定ID的文檔不存在,Elasticsearch將返回一個錯誤,指出該文檔丟失。
在這裏插入圖片描述
doc_as_upsert參數檢查具有給定ID的文檔是否已經存在,並將提供的doc與現有文檔合併。 如果不存在具有給定ID的文檔,則會插入具有給定文檔內容的新文檔。

下面的示例使用doc_as_upsert合併到ID爲3的文檔中,或者如果不存在則插入一個新文檔:
在這裏插入圖片描述
在這裏插入圖片描述

檢查文檔是否存在

  • 有時候想知道一個文檔是否存在,可以使用如下的方法:
    HEAD 索引/類型/文檔id
    在這裏插入圖片描述
    在這裏插入圖片描述

刪除文檔

  • 如果想刪除一個文檔的話,可以使用如下的命令:
    DELETE 索引/類型/文檔id
    在這裏插入圖片描述
    在這裏插入圖片描述
  • 在關係數據庫中,通常是對數據庫進行搜索,然後才進行刪除。在這種情況下,事先通常並不知道文檔的id。需要通過查詢的方式來進行查詢,讓後進行刪除。ES也提供了相應的REST接口。
POST twitter/_delete_by_query
{
  "query": {
    "match": {
      "city": "上海"
    }
  }
}

這樣我們就把所有的city是上海的文檔都刪除了。

刪除索引

除一個index是非常直接的。可以直接使用如下的命令來進行刪除:
DELETE 索引
在這裏插入圖片描述

批處理命令

瞭解瞭如何使用REST接口來創建一個index,併爲之創建,讀取,修改,刪除文檔(CRUD)。因爲每一次操作都是一個REST請求,對於大量的數據進行操作的話,這個顯得比較慢。ES創建一個批量處理的命令供使用。這樣在一次REST請求中,就可以完成很多的操作。

使用如下的命令來進行bulk操作:

POST _bulk
{ "index" : { "_index" : "twitter", "_id": 1} }
{"user":"雙榆樹-張三","message":"今兒天氣不錯啊,出去轉轉去","uid":2,"age":20,"city":"北京","province":"北京","country":"中國","address":"中國北京市海淀區","location":{"lat":"39.970718","lon":"116.325747"}}
{ "index" : { "_index" : "twitter", "_id": 2 }}
{"user":"東城區-老劉","message":"出發,下一站雲南!","uid":3,"age":30,"city":"北京","province":"北京","country":"中國","address":"中國北京市東城區臺基廠三條3號","location":{"lat":"39.904313","lon":"116.412754"}}
{ "index" : { "_index" : "twitter", "_id": 3} }
{"user":"東城區-李四","message":"happy birthday!","uid":4,"age":30,"city":"北京","province":"北京","country":"中國","address":"中國北京市東城區","location":{"lat":"39.893801","lon":"116.408986"}}
{ "index" : { "_index" : "twitter", "_id": 4} }
{"user":"朝陽區-老賈","message":"123,gogogo","uid":5,"age":35,"city":"北京","province":"北京","country":"中國","address":"中國北京市朝陽區建國門","location":{"lat":"39.718256","lon":"116.367910"}}
{ "index" : { "_index" : "twitter", "_id": 5} }
{"user":"朝陽區-老王","message":"Happy BirthDay My Friend!","uid":6,"age":50,"city":"北京","province":"北京","country":"中國","address":"中國北京市朝陽區國貿","location":{"lat":"39.918256","lon":"116.467910"}}
{ "index" : { "_index" : "twitter", "_id": 6} }
{"user":"虹橋-老吳","message":"好友來了都今天我生日,好友來了,什麼 birthday happy 就成!","uid":7,"age":90,"city":"上海","province":"上海","country":"中國","address":"中國上海市閔行區","location":{"lat":"31.175927","lon":"121.383328"}}

在這裏插入圖片描述
在上面的命令中,使用了bulk指令來完成我們的操作。在輸入命令時,們需要特別的注意:不要添加除了換行以外的空格,否則會導致錯誤。爲了說明問題的方便,在每一個文檔裏,特別指定了每個文檔的id。
bulk指令是高效的,因爲一個請求就可以處理很多個操作。在實際的使用中,必須注意的是:一個好的起點是批量處理1000到5,000個文檔,總有效負載在5MB到15MB之間。如果payload過大,那麼可能會造成請求的失敗。如果你想更進一步探討的話,可以使用文件accounts.json來做實驗。

  • 上面已經使用了index來創建6條文檔記錄。也可以嘗試其它的命令,比如create:
POST _bulk
{ "create" : { "_index" : "twitter", "_id": 1} }
{"user":"雙榆樹-張三","message":"今兒天氣不錯啊,出去轉轉去","uid":2,"age":20,"city":"北京","province":"北京","country":"中國","address":"中國北京市海淀區","location":{"lat":"39.970718","lon":"116.325747"}}
{ "index" : { "_index" : "twitter", "_id": 2 }}
{"user":"東城區-老劉","message":"出發,下一站雲南!","uid":3,"age":30,"city":"北京","province":"北京","country":"中國","address":"中國北京市東城區臺基廠三條3號","location":{"lat":"39.904313","lon":"116.412754"}}
{ "index" : { "_index" : "twitter", "_id": 3} }
{"user":"東城區-李四","message":"happy birthday!","uid":4,"age":30,"city":"北京","province":"北京","country":"中國","address":"中國北京市東城區","location":{"lat":"39.893801","lon":"116.408986"}}
{ "index" : { "_index" : "twitter", "_id": 4} }
{"user":"朝陽區-老賈","message":"123,gogogo","uid":5,"age":35,"city":"北京","province":"北京","country":"中國","address":"中國北京市朝陽區建國門","location":{"lat":"39.718256","lon":"116.367910"}}
{ "index" : { "_index" : "twitter", "_id": 5} }
{"user":"朝陽區-老王","message":"Happy BirthDay My Friend!","uid":6,"age":50,"city":"北京","province":"北京","country":"中國","address":"中國北京市朝陽區國貿","location":{"lat":"39.918256","lon":"116.467910"}}
{ "index" : { "_index" : "twitter", "_id": 6} }
{"user":"虹橋-老吳","message":"好友來了都今天我生日,好友來了,什麼 birthday happy 就成!","uid":7,"age":90,"city":"上海","province":"上海","country":"中國","address":"中國上海市閔行區","location":{"lat":"31.175927","lon":"121.383328"}}

在上面使用了create來創建第一個id爲1的記錄。因爲之前已經創建過了,所以可以看到如下的信息:
在這裏插入圖片描述
從上面的信息,可以看出來index和create的區別。index總是可以成功,它可以覆蓋之前的已經創建的文檔,但是create則不行,如果已經有以那個id爲名義的文檔,就不會成功。

  • 批量刪除命令
POST _bulk
{ "delete" : { "_index" : "索引", "_id": id1 }}
{ "delete" : { "_index" : "索引", "_id": id2 }}
  • 批量更新命令
POST _bulk
{ "update" : { "_index" : "索引", "_id": id1 }}
{"doc": { "字段": "new date"}}
{ "update" : { "_index" : "索引", "_id": id2 }}
{"doc": { "字段1": "new datr","字段2":"new date"}}

注意:通過bulk API爲數據編制索引時,不應在集羣上進行任何查詢/搜索。 這樣做可能會導致嚴重的性能問題。

查詢索引

  • 如果想查詢到所有的輸入的文檔,可以使用如下的命令來進行查詢:
    POST 索引/_search
    在這裏插入圖片描述
    上面的結果顯示,已經有6條文檔記錄產生了。
  • 可以通過使用_count命令來查詢有多少條數據:
    GET 索引/_count
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章