elasticsearch【更新】操作


基於上一篇博文基礎上,進行es的操作,document的新增比較簡單,就不說了,這里主要說說更新操作。

 

更新操作,有兩大類,一個是Replace,一個是Update,就是說一個是替換,一個是更新。 替換,就是全文檔更換,而更新可以只針對文檔的局部字段。

 

1. 這里先說簡單的Replace的操作。

先創建一個document,索引名為gengxin,文檔類型為replace。

 1 [water@CloudGame ES]$ curl -XPUT 'localhost:9200/gengxin/replace/1?pretty' -d '
 2 { 
 3   "name": "shihuc",
 4   "job": "System Software Dev Manager",
 5   "date": "2016-10-19"
 6 }'
 7 {
 8   "_index" : "gengxin",
 9   "_type" : "replace",
10   "_id" : "1",
11   "_version" : 1,                   
12   "_shards" : {
13     "total" : 2,
14     "successful" : 1,
15     "failed" : 0
16   },
17   "created" : true                  #注意,這里的信息狀態是true
18 }

查詢看看創建的結果:

 1 [water@CloudGame ES]$ curl "localhost:9200/gengxin/replace/1?pretty"
 2 {
 3   "_index" : "gengxin",
 4   "_type" : "replace",
 5   "_id" : "1",
 6   "_version" : 1,
 7   "found" : true,
 8   "_source" : {
 9     "name" : "shihuc",
10     "job" : "System Software Dev Manager",
11     "date" : "2016-10-19"
12   }
13 }

沒有什么問題。 然后我們對這個id為1的document進行replace操作:

 1 [water@CloudGame ES]$ curl -XPUT 'localhost:9200/gengxin/replace/1?pretty' -d '
 2 { 
 3   "name": "wdn",
 4   "job": "TK CEO"
 5 }'
 6 {
 7   "_index" : "gengxin",
 8   "_type" : "replace",
 9   "_id" : "1",
10   "_version" : 2,
11   "_shards" : {
12     "total" : 2,
13     "successful" : 1,
14     "failed" : 0
15   },
16   "created" : false           #注意,這里的狀態是false喲,表示沒有新建一個
17 }

再查看一下,這個被replace了的document內容:

 1 [water@CloudGame ES]$ curl "localhost:9200/gengxin/replace/1?pretty"
 2 {
 3   "_index" : "gengxin",
 4   "_type" : "replace",
 5   "_id" : "1",
 6   "_version" : 2,
 7   "found" : true,
 8   "_source" : {
 9     "name" : "wdn",
10     "job" : "TK CEO"
11   }
12 }

發現沒有,這個被Replace后的數據,與新建的時候字段數量都不一樣了,就和一個新建很類似。內容完全被替換了。

 

2. 下面看看Update更新操作,其實,這個操作是針對已經建立的document修改field的內容,字段field的名字和數量是不能被修改的,是不是差別出來了???對的,就是這個差別。

 1 [water@CloudGame ES]$ curl -XPUT 'localhost:9200/gengxin/update/1?pretty' -d '
 2 { 
 3   "name": "water",
 4   "job": "跑龍套的寶寶",
 5   "date": "2016-10-19"
 6 }'
 7 {
 8   "_index" : "gengxin",
 9   "_type" : "update",
10   "_id" : "1",
11   "_version" : 1,
12   "_shards" : {
13     "total" : 2,
14     "successful" : 1,
15     "failed" : 0
16   },
17   "created" : true
18 }

查看返回值:

 1 [water@CloudGame ES]$ curl "localhost:9200/gengxin/update/1?pretty"
 2 {
 3   "_index" : "gengxin",
 4   "_type" : "update",
 5   "_id" : "1",
 6   "_version" : 1,
 7   "found" : true,
 8   "_source" : {
 9     "name" : "water",
10     "job" : "跑龍套的寶寶", 11     "date" : "2016-10-19"
12   }
13 }

再來看看Update的操作:

 1 [water@CloudGame ES]$ curl -XPOST "localhost:9200/gengxin/update/1/_update?pretty" -d '
 2 {
 3   "doc": {"job": "奮斗者"}
 4 }'
 5 {
 6   "_index" : "gengxin",
 7   "_type" : "update",
 8   "_id" : "1",
 9   "_version" : 5,
10   "_shards" : {
11     "total" : 2,
12     "successful" : 1,
13     "failed" : 0
14   }
15 }

查看Update的結果:

 1 [water@CloudGame ES]$ curl "localhost:9200/gengxin/update/1?pretty"
 2 {
 3   "_index" : "gengxin",
 4   "_type" : "update",
 5   "_id" : "1",
 6   "_version" : 5,
 7   "found" : true,
 8   "_source" : {
 9     "name" : "water",
10     "job" : "奮斗者", 11     "date" : "2016-10-19"
12   }
13 }

到此,是不是發現Replace操作和Update操作的不同了?

1. 指令不同,replace前后都是PUT指令,其實,用POST也可以實現replace,比如上面的replace操作的時候,將PUT換成POST也可以的。但是最好還是用PUT, http指令中POST是用來更新數據的,PUT是用來新增數據用的,雖然兩個沒有嚴格的限制。還有,在做Update操作時,指令中含有關鍵字_update.

2. replace操作時,指令的-d的內容就是最后的數據的內容,也就是查詢結果中_source中的內容,但是Update的操作,修改的只是_source中的某些字段的內容

 

另外,補充一下Update的操作,其實除了通過doc來修改指定的字段內容,還可以通過script來實現字段內容的修改。script的東西就比較多了,這里簡單的演示一個inline的腳本處理,作為引子簡單介紹下!

A. 創建一個文檔,並查看結果, 文檔的內容是說wangbaoqiang有幾頂綠帽子,開始創建的時候寫的是2個,后來發現其實只有馬rong個jian人一個,於是乎要修改。。。

 1 [water@CloudGame ES]$ curl -XPUT "localhost:9200/gengxin/update/2?pretty" -d '{
 2 > "name": "wangbaoqiang",
 3 > "green_hat": "2"
 4 > }'
 5 {
 6   "_index" : "gengxin",
 7   "_type" : "update",
 8   "_id" : "2",
 9   "_version" : 1,
10   "_shards" : {
11     "total" : 2,
12     "successful" : 1,
13     "failed" : 0
14   },
15   "created" : true
16 }
17 [water@CloudGame ES]$ 
18 [water@CloudGame ES]$ curl "localhost:9200/gengxin/update/2?pretty"
19 {
20   "_index" : "gengxin",
21   "_type" : "update",
22   "_id" : "2",
23   "_version" : 1,
24   "found" : true,
25   "_source" : {
26     "name" : "wangbaoqiang",
27     "green_hat" : "2"
28   }
29 }

好吧,進行修改吧(行內腳本的方式實現):

 1 [water@CloudGame ES]$ curl -XPOST "localhost:9200/gengxin/update/2/_update?pretty" -d '{
 2 > "script": "ctx._source.green_hat = count",
 3 > "inline": {
 4 >    "params" : {
 5 >      "count" : 1
 6 >    }
 7 >  }
 8 > }'
 9 {
10   "error" : {
11     "root_cause" : [ {
12       "type" : "remote_transport_exception",
13       "reason" : "[node-1][10.90.6.172:9300][indices:data/write/update[s]]"
14     } ],
15     "type" : "illegal_argument_exception",
16     "reason" : "failed to execute script",
17     "caused_by" : {
18       "type" : "script_exception",
19       "reason" : "scripts of type [inline], operation [update] and lang [groovy] are disabled"
20     }
21   },
22   "status" : 400
23 }

報錯了,意思是說行內腳本通過groovy語言執行update操作是被禁用了的。 查看幫助文檔吧,發現script章節有介紹,需要修改elasticsearch.yml配置文件,再其最后,加入下面的內容,重新啟動es:

1  script.inline: true
2  script.indexed: true
3  script.engine.groovy.inline.aggs: true

 

重啟ES后,再次操作上述script方式的update指令:

 1 [water@CloudGame ES]$ curl -XPOST "localhost:9200/gengxin/update/2/_update?pretty" -d '{
 2 "script": "ctx._source.green_hat = count",
 3 "inline": {
 4    "params" : {
 5      "count" : 1
 6    }
 7  }
 8 }'
 9 {
10   "_index" : "gengxin",
11   "_type" : "update",
12   "_id" : "2",
13   "_version" : 4,
14   "_shards" : {
15     "total" : 2,
16     "successful" : 1,
17     "failed" : 0
18   }
19 }
20 [water@CloudGame ES]$ 
21 [water@CloudGame ES]$ curl "localhost:9200/gengxin/update/2?pretty"
22 {
23   "_index" : "gengxin",
24   "_type" : "update",
25   "_id" : "2",
26   "_version" : 4,
27   "found" : true,
28   "_source" : {
29     "name" : "wangbaoqiang",
30     "green_hat" : 1
31   }
32 }

是不是也還不錯,比較容易實現。

補充一點tip,若update操作中doc和script關鍵字都出現了,那么doc將被忽略!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM