ElasticSearch學(xué)習(xí)之文檔API相關(guān)操作
前言
本節(jié)主要給大家講一下文檔API相關(guān)操作。在學(xué)習(xí)之前,建議大家先回顧前幾節(jié)內(nèi)容,讓自己有一個(gè)整體的認(rèn)知,不要把概念混淆了。我們前幾節(jié)都在講索引
,它是和文檔掛鉤的,文檔我們可以理解為數(shù)據(jù)
,數(shù)據(jù)有增刪改查
,本節(jié)就主要跟大家講一下文檔
的增刪改查操作。
本文偏實(shí)戰(zhàn)一些,好了, 廢話不多說(shuō)直接開(kāi)整吧~
創(chuàng)建文檔
這里沿用之前的例子,使用class_1
的索引,我們先看下它的索引結(jié)構(gòu):
GET /class_1
返回:
{ "class_1" : { "aliases" : { "class" : { } }, "mappings" : { "properties" : { "name" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "num" : { "type" : "long" } } }, "settings" : { "index" : { "refresh_interval" : "3s", "number_of_shards" : "3", "provided_name" : "class_1", "creation_date" : "1670812583980", "number_of_replicas" : "1", "uuid" : "CTD3dM-fQm-KFEVl4nAgRQ", "version" : { "created" : "7060299" } } } } }
通過(guò)結(jié)構(gòu)可以看到,它主要有兩個(gè)字段name
和num
,那么我們?cè)趺赐镞吿砑訑?shù)據(jù)呢?
創(chuàng)建文檔分為以下幾種情況:
- 創(chuàng)建
單個(gè)數(shù)據(jù)指定ID
:使用_doc
路由+PUT
請(qǐng)求+id
參數(shù) - 創(chuàng)建
單個(gè)數(shù)據(jù)不指定ID
:使用_doc
路由+POST
請(qǐng)求 - 創(chuàng)建
單個(gè)數(shù)據(jù)指定ID并進(jìn)行ID唯一性控制
:使用_doc
路由+PUT
請(qǐng)求+id
參數(shù)+op_type=create
參數(shù) - 創(chuàng)建
批量數(shù)據(jù)指定ID
:使用_bulk
路由+PUT
請(qǐng)求/POST
請(qǐng)求+create
關(guān)鍵字+_id
屬性 - 創(chuàng)建
批量數(shù)據(jù)不指定ID
:使用_bulk
路由+PUT
請(qǐng)求/POST
請(qǐng)求+create
關(guān)鍵字
下面,帶大家一個(gè)一個(gè)看
單個(gè)數(shù)據(jù)
指定ID
PUT /class_1/_doc/1 { "name":"a", "num": 5 }
創(chuàng)建成功返回:
{ "_index" : "class_1", "_type" : "_doc", "_id" : "1", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 1, "_primary_term" : 3 }
不指定ID
PUT /class_1/_doc/ { "name":"b", "num": 6 }
{ "error" : "Incorrect HTTP method for uri [/class_1/_doc/?pretty=true] and method [PUT], allowed: [POST]", "status" : 405 }
創(chuàng)建失敗了,告訴我們這里要使用POST
POST /class_1/_doc/ { "name":"b", "num": 6 }
{ "_index" : "class_1", "_type" : "_doc", "_id" : "h2Fg-4UBECmbBdQA6VLg", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 0, "_primary_term" : 3 }
可以看到不指定id情況下,創(chuàng)建的文檔_id
隨機(jī)生成了
ID唯一性控制
PUT /class_1/_doc/1?op_type=create { "name":"c", "num": 7 }
{ "error" : { "root_cause" : [ { "type" : "version_conflict_engine_exception", "reason" : "[1]: version conflict, document already exists (current version [1])", "index_uuid" : "CTD3dM-fQm-KFEVl4nAgRQ", "shard" : "2", "index" : "class_1" } ], "type" : "version_conflict_engine_exception", "reason" : "[1]: version conflict, document already exists (current version [1])", "index_uuid" : "CTD3dM-fQm-KFEVl4nAgRQ", "shard" : "2", "index" : "class_1" }, "status" : 409 }
可以看到,創(chuàng)建失敗了,返回document already exists
批量數(shù)據(jù)
指定ID
PUT class_1/_bulk { "create":{ "_id": 2 } } {"name":"d","num": 8} { "create":{ "_id": 3 } } { "name":"e","num": 9} { "create":{ "_id": 4 } } {"name":"f","num": 10}
tip: 這里要注意,不能有空行,json對(duì)象{}需要在同一行
{ "took" : 25, "errors" : false, "items" : [ { "create" : { "_index" : "class_1", "_type" : "_doc", "_id" : "2", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 0, "_primary_term" : 4, "status" : 201 } }, { "create" : { "_index" : "class_1", "_type" : "_doc", "_id" : "3", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 1, "_primary_term" : 4, "status" : 201 } }, { "create" : { "_index" : "class_1", "_type" : "_doc", "_id" : "4", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 2, "_primary_term" : 4, "status" : 201 } } ] }
不指定ID
很簡(jiǎn)單,去掉id
屬性就好了~
PUT class_1/_bulk { "create":{ } } {"name":"g","num": 8} { "create":{ } } { "name":"h","num": 9} { "create":{ } } {"name":"i","num": 10}
{ "took" : 30, "errors" : false, "items" : [ { "create" : { "_index" : "class_1", "_type" : "_doc", "_id" : "iGFt-4UBECmbBdQAnVJe", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 3, "_primary_term" : 4, "status" : 201 } }, { "create" : { "_index" : "class_1", "_type" : "_doc", "_id" : "iWFt-4UBECmbBdQAnVJg", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 4, "_primary_term" : 4, "status" : 201 } }, { "create" : { "_index" : "class_1", "_type" : "_doc", "_id" : "imFt-4UBECmbBdQAnVJg", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 5, "_primary_term" : 4, "status" : 201 } } ] }
修改文檔
文檔修改分以下幾種情況:
- 按照
ID
全量更新單個(gè)
數(shù)據(jù):使用_doc
路由+PUT
請(qǐng)求+id
參數(shù) - 按照
ID
全量更新單個(gè)
數(shù)據(jù)并進(jìn)行樂(lè)觀鎖
控制:使用_doc
路由+PUT
請(qǐng)求+if_seq_no&if_primary_term
參數(shù)+id
參數(shù) - 按照
ID
部分更新單個(gè)
數(shù)據(jù)(包含屬性添加):使用_update
路由+POST
請(qǐng)求+id
參數(shù) - 按照
ID
全量更新批量
數(shù)據(jù):使用_bulk
路由+PUT
請(qǐng)求/POST
請(qǐng)求+index
關(guān)鍵字+_id
屬性 - 按照
ID
部分更新批量
數(shù)據(jù)(包含屬性添加):使用_bulk
路由+PUT
請(qǐng)求/POST
請(qǐng)求+update
關(guān)鍵字+_id
屬性 - 按照條件
修改
數(shù)據(jù):使用_update_by_query
路由+POST
請(qǐng)求+ctx._source[字段名稱]
=字段值 - 按照條件給數(shù)據(jù)
新增
屬性:使用_update_by_query
路由+POST
請(qǐng)求+ctx._source[字段名稱]
=字段值 - 按照條件給數(shù)據(jù)
移除
屬性:使用_update_by_query
路由+POST
請(qǐng)求+ctx._source.remove
(字段名稱)
同樣的,帶大家一個(gè)個(gè)來(lái)看~
按照ID單個(gè)
全量更新
PUT /class_1/_doc/1 { "name":"k", "num": 5 }
{ "_index" : "class_1", "_type" : "_doc", "_id" : "1", "_version" : 2, "result" : "updated", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 2, "_primary_term" : 3 }
再次修改:
PUT /class_1/_doc/1 { "name":"k", "num": 6 }
{ "_index" : "class_1", "_type" : "_doc", "_id" : "1", "_version" : 3, "result" : "updated", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 3, "_primary_term" : 3 }
大家觀察一下這個(gè)_version
字段,發(fā)現(xiàn)它的版本號(hào)是遞增的,也就是說(shuō)會(huì)隨著我們的修改而變化
基于樂(lè)觀鎖全量更新
跟上條件if_seq_no,if_primary_term
PUT /class_1/_doc/1?if_seq_no=3&if_primary_term=3 { "name":"l", "num": 6 }
{ "_index" : "class_1", "_type" : "_doc", "_id" : "1", "_version" : 4, "result" : "updated", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 4, "_primary_term" : 3 }
再操作一下:
{ "error" : { "root_cause" : [ { "type" : "version_conflict_engine_exception", "reason" : "[1]: version conflict, required seqNo [3], primary term [3]. current document has seqNo [4] and primary term [3]", "index_uuid" : "CTD3dM-fQm-KFEVl4nAgRQ", "shard" : "2", "index" : "class_1" } ], "type" : "version_conflict_engine_exception", "reason" : "[1]: version conflict, required seqNo [3], primary term [3]. current document has seqNo [4] and primary term [3]", "index_uuid" : "CTD3dM-fQm-KFEVl4nAgRQ", "shard" : "2", "index" : "class_1" }, "status" : 409 }
發(fā)現(xiàn)操作失敗了,因?yàn)闂l件不符合 required seqNo [3], primary term [3]
,上一步操作完之后seqNo和primary term [4]
部分更新
PUT /class_1/_update/1 { "doc":{ "name":"m", "num": 1 } }
按照ID批量
全量更新
PUT class_1/_bulk { "create":{ "_id": 2 } } {"name":"d","num": 8} { "create":{ "_id": 3 } } { "name":"e","num": 9} { "create":{ "_id": 4 } } {"name":"f","num": 10}
這個(gè)應(yīng)該好理解
部分更新
需要修改為update
并添加屬性
PUT class_1/_bulk { "update":{ "_id": 2 } } { "doc":{"name":"d","num": 8}} { "update":{ "_id": 3 } } { "doc":{ "name":"e","num": 9}} { "update":{ "_id": 4 } } { "doc":{"name":"f","num": 10}}
返回:
{ "took" : 32, "errors" : false, "items" : [ { "update" : { "_index" : "class_1", "_type" : "_doc", "_id" : "2", "_version" : 2, "result" : "updated", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 6, "_primary_term" : 4, "status" : 200 } }, { "update" : { "_index" : "class_1", "_type" : "_doc", "_id" : "3", "_version" : 2, "result" : "updated", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 7, "_primary_term" : 4, "status" : 200 } }, { "update" : { "_index" : "class_1", "_type" : "_doc", "_id" : "4", "_version" : 2, "result" : "updated", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 8, "_primary_term" : 4, "status" : 200 } } ] }
按照條件修改
修改字段
查找name=d
的數(shù)據(jù)修改為num=10,name=e
POST class_1/_update_by_query { "query": { "match": { "name": "d" } }, "script": { "source": "ctx._source['num']='10';ctx._source['name']='e'", "lang": "painless" } }
返回:
{ "took" : 108, "timed_out" : false, "total" : 1, "updated" : 1, "deleted" : 0, "batches" : 1, "version_conflicts" : 0, "noops" : 0, "retries" : { "bulk" : 0, "search" : 0 }, "throttled_millis" : 0, "requests_per_second" : -1.0, "throttled_until_millis" : 0, "failures" : [ ] }
增加字段
POST class_1/_update_by_query { "query": { "match": { "name": "e" } }, "script": { "source": "ctx._source['desc']=['hhhh']", "lang": "painless" } }
{ "took" : 344, "timed_out" : false, "total" : 2, "updated" : 2, "deleted" : 0, "batches" : 1, "version_conflicts" : 0, "noops" : 0, "retries" : { "bulk" : 0, "search" : 0 }, "throttled_millis" : 0, "requests_per_second" : -1.0, "throttled_until_millis" : 0, "failures" : [ ] }
接著我們查下class_1
的索引結(jié)構(gòu):
{ "class_1" : { "aliases" : { "class" : { } }, "mappings" : { "properties" : { "age" : { "type" : "long" }, "desc" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "name" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "num" : { "type" : "long" } } }, "settings" : { "index" : { "refresh_interval" : "3s", "number_of_shards" : "3", "provided_name" : "class_1", "creation_date" : "1670812583980", "number_of_replicas" : "1", "uuid" : "CTD3dM-fQm-KFEVl4nAgRQ", "version" : { "created" : "7060299" } } } } }
可以看到多了一個(gè)字段:
{ "desc" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } } }
移除字段
POST class_1/_update_by_query { "query": { "match": { "name": "e" } }, "script": { "source": "ctx._source.remove('desc')", "lang": "painless" } }
大家可以試著運(yùn)行一下,然后再查下索引
刪除文檔
按照ID & 單個(gè)刪除
DELETE /class_1/_doc/2
{ "_index" : "class_1", "_type" : "_doc", "_id" : "2", "_version" : 5, "result" : "deleted", "_shards" : { "total" : 2, "successful" : 2, "failed" : 0 }, "_seq_no" : 12, "_primary_term" : 4 }
按照ID & 批量刪除
PUT class_1/_bulk { "delete":{"_id":"2" } } { "delete":{"_id":"3" } }
按照條件刪除
POST class_1/_delete_by_query { "query":{ "match_all":{ "name": "e" } } }
結(jié)束語(yǔ)
本節(jié)主要講了ES中的文檔API操作
,還遺留一個(gè)查詢
操作, 該部分內(nèi)容較多,放到后邊給大家講,更多關(guān)于ElasticSearch文檔API操作的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Elasticsearch學(xué)習(xí)之Terms?set?查詢
- ElasticSearch學(xué)習(xí)之Es索引Api操作
- ElasticSearch學(xué)習(xí)之Es集群Api操作示例
- ElasticSearch學(xué)習(xí)之ES Mapping實(shí)戰(zhàn)示例
- ElasticSearch 動(dòng)態(tài)映射實(shí)戰(zhàn)詳解
- Elasticsearch?計(jì)數(shù)分詞中的token使用實(shí)例
- Elasticsearch?percolate?查詢示例詳解
- ElasticSearch學(xué)習(xí)之多條件組合查詢驗(yàn)證及示例分析
相關(guān)文章
Spring如何配置文件動(dòng)態(tài)讀取pom.xml中的屬性
在項(xiàng)目開(kāi)發(fā)中,經(jīng)常需要將pom.xml中的屬性動(dòng)態(tài)傳遞給Spring配置文件,實(shí)現(xiàn)這一需求,可通過(guò)Maven的資源過(guò)濾功能,配置占位符替換,具體方法包括:在pom.xml中啟用filtering,然后在Spring配置文件中通過(guò)${property}方式引用屬性2024-10-10MyBatis-Plus?條件查詢器的實(shí)現(xiàn)
本文主要介紹了MyBatis-Plus?條件查詢器的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07Java中的while循環(huán)語(yǔ)句詳細(xì)講解
這篇文章主要給大家介紹了關(guān)于Java中while循環(huán)語(yǔ)句的相關(guān)資料,while循環(huán)是一種在編程中常見(jiàn)的控制流語(yǔ)句,它允許代碼在特定條件下(通常是一個(gè)布爾表達(dá)式)重復(fù)執(zhí)行一段代碼,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-03-03JAVA使用隨機(jī)數(shù)實(shí)現(xiàn)概率抽獎(jiǎng)
這篇文章主要為大家詳細(xì)介紹了JAVA使用隨機(jī)數(shù)實(shí)現(xiàn)概率抽獎(jiǎng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11java隊(duì)列中Queue與Deque的區(qū)別面試精講
這篇文章主要為大家介紹了java隊(duì)列中Queue與Deque的區(qū)別面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10Java如何對(duì)返回參數(shù)進(jìn)行處理
這篇文章主要介紹了Java如何對(duì)返回參數(shù)進(jìn)行處理問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07