基於上一篇博文基礎上,進行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將被忽略!