目錄shell
說在前面: 本文的全部演示, 都是基於Elasticsearch 6.6.10進行的, 不一樣的版本可能存在API發生修改、不支持的狀況, 還請注意.json
(1) 適用情景:安全
從其餘系統中導入數據到ES時, 會採起這種方式: 使用原有系統中數據已有的惟一標識, 做爲ES中document的id.bash
而若是數據一輩子產出來就存儲到了ES中, 通常是不適合手動指定id的.服務器
(2) 使用語法:併發
put index/type/id
(3) 使用示例:分佈式
PUT employee/developer/1 { "name": "shoufeng", "e_id": 5220 }
(4) 添加成功後的響應信息:ui
{ "_index" : "employee", "_type" : "developer", "_id" : "1", // 指定了id, 控制底層的_id元字段 "_version" : 1, // 當前版本號, 基於此字段進行併發控制 "result" : "created", "_shards" : { "total" : 2, // 參與建立的分片數, 包括Primary和Replica "successful" : 1, // 成功建立索引的分片數量 "failed" : 0 // 建立索引失敗的分片數量 }, "_seq_no" : 0, "_primary_term" : 1 }
(1) 使用情景:編碼
ES做爲數據存儲服務器, 應用程序中的數據直接對接到ES中, 這種場景適合自動生成id.code
在多節點併發生成大量數據的場景下, 自動生成id更具安全性.
(2) 使用語法:
POST index/type
(3) 使用示例:
POST employee/developer { "name": "shoufeng", "sex": "male", "age": 20 }
(4) 添加成功後的響應結果:
{ "_index" : "employee", "_type" : "developer", "_id" : "vMxcFWoBfKUnm9s_Uxen", // 沒有指定id, 就會自動生成id, 長度爲20個字符 "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "_seq_no" : 0, "_primary_term" : 1 }
官方文檔中指出:
Elasticsearch自動生成的id, 長度爲20個字符, 是URL安全的, 它是Base64編碼的GUID字符串, 多節點(分佈式系統)並行生成id時不會發生衝突.
查詢時能夠不指定type, 即下述的developer, 而用_all代替.
// 查詢語法: GET employee/developer/1 // 結果以下: { "_index" : "employee", "_type" : "developer", "_id" : "1", "_version" : 1, "_seq_no" : 0, "_primary_term" : 1, "found" : true, "_source" : { // 文檔的元數據 "name" : "shoufeng", "e_id" : 5220 } }
(1) 只獲取指定id的文檔的_source
內容:
GET employee/developer/1/_source // 結果是: { "name" : "shoufeng", "e_id" : 5220 }
(2) 禁用指定id的文檔的_source
字段:
GET employee/developer/1?_source=false // 結果是: { "_index" : "employee", "_type" : "developer", "_id" : "1", "_version" : 1, "_seq_no" : 0, "_primary_term" : 1, "found" : true }
(3) 過濾_source
中的某些field:
// _source_includes和_source_excludes能夠匹配通配符* GET employee/developer/1?_source_includes=name,age&_source_excludes=sex GET employee/developer/_search?_source_includes=name,age&_source_excludes=sex
(4) 經過stored_fields
API過濾文檔中已存儲的字段:
在Elasticsearch 6.0以後, 再也不支持
fields
, 須要使用stored_fields
API替換.
GET employee/developer/1?stored_fields=name,age // 指定id GET employee/developer/_search?stored_fields=name,age // 不指定id, 將查詢全部文檔
其餘查詢操做, 將在後續的文章中專門記錄.
全量替換是基於指定文檔id的修改:
// 語法與建立語法相同: PUT employee/developer/1 { "name": "shoufeng001", // 修改姓名 "age": 20, // 添加年齡 "sex": "male", // 添加性別 "e_id": 5220 }
操做過程說明:
① 若是指定的document id不存在, 就是建立操做;
② 若是指定的document id已經存在, 就是全量替換操做 —— 替換舊文檔的JSON串內容;
③ Lucene中倒排索引一旦被建立就是不可變的, 要修改文檔內容, 能夠採起全量替換的方式 —— 對文檔從新創建索引, 替換舊文檔的全部內容;
④ ES會將舊文檔標記爲deleted, 而後根據咱們提交的請求建立一個新文檔, 當標記爲deleted的文檔數達到必定量時, ES會在自動刪除這些舊文檔.
(1) 存在這樣的場景:
咱們不知道索引中是否已經存在某個文檔 —— 可能有其餘用戶在併發添加文檔;
爲了防止建立操做被執行爲全量替換操做, 從而致使數據的丟失, 咱們可使用強制建立的方式, 來避免這種失誤.
(2) 強制建立示例:
PUT employee/developer/1?op_type=create { "name": "shoufeng", "age": 20 } // 或者使用: PUT employee/developer/1/_create { "name": "shoufeng", "age": 20 } // 響應結果中出現衝突: { "error": { "root_cause": [ { // 因爲文檔已經存在, 發生版本衝突, 致使建立失敗 "type": "version_conflict_engine_exception", "reason": "[developer][1]: version conflict, document already exists (current version [2])", "index_uuid": "OYu6J2x_S2S5v-R74aq6NQ", "shard": "3", "index": "employee" } ], "type": "version_conflict_engine_exception", "reason": "[developer][1]: version conflict, document already exists (current version [2])", "index_uuid": "OYu6J2x_S2S5v-R74aq6NQ", "shard": "3", "index": "employee" }, "status": 409 }
出現衝突的緣由:
① Elasticsearch經過樂觀鎖控制每一個文檔的
_version
信息, 強制建立語法會對當前操做的文檔的_version
信息進行初始化;② 添加索引時, 發現已經存在對應id的文檔, 並且其版本號與正在強制建立的文檔的版本信息不匹配, 因此報錯.
出現衝突後, 咱們就能知道索引中已存在該文檔了, 就能夠根據本身的應用需求, 採起更改id後從新添加, 或者更改已有的文檔等操做.
(1) 刪除語法:
DELETE index/type/id
(2) 刪除示例:
DELETE employee/developer/1 // 再次查看id爲1的文檔, 發現"found": false
(3) Elasticsearch刪除文檔採起的是懶刪除機制:
不會當即物理刪除, 而是將其標記爲deleted, 當被刪除的文檔數量達到必定級別後, ES會在後臺自動刪除這些文檔.
版權聲明
做者: 馬瘦風
出處: 博客園 馬瘦風的博客
您的支持是對博主的極大鼓勵, 感謝您的閱讀.
本文版權歸博主全部, 歡迎轉載, 但請保留此段聲明, 並在文章頁面明顯位置給出原文連接, 不然博主保留追究相關人員法律責任的權利.