es重建字段类型_关于elasticsearch中更新数据的几种方式
作為一個成熟的框架,Elasticsearch里面提供了豐富的操作數據的api,本篇我們就來學習一下在es中更新數據的幾種方式。
(一)更新文檔
(1)部分更新:
java api:
` HashMap data=new HashMap<>();
data.put("name","woshigcs");
data.put("age",25);
UpdateRequestBuilder urb= client.prepareUpdate("active2018-03-21", "active", "18");
urb.setDoc(data);
urb.execute().actionGet();
System.out.println("update ok......");
注意部分更新功能,前提是索引和該條數據已經存在,否則會拋出對應的異常,只要任何一個不滿足,都會更新失敗。
curl:
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"doc" : {
"name" : "new_name"
}
}
(2)使用detect_noop
java api:
` HashMap data=new HashMap<>();
data.put("name","woshigcs");
data.put("age",25);
UpdateRequestBuilder urb= client.prepareUpdate("active2018-03-21", "active", "18");
urb.setDoc(data);
urb.setDetectNoop(false);//默認是true
urb.execute().actionGet();
System.out.println("update ok......");
curl方式:
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"doc" : {
"name" : "new_name"
},
"detect_noop": false
}'
注意detect_noop的意思:
默認情況下detect_noop=true
默認情況下只有原來的source和新的source存在不同的字段情況下才會重建索引,如果一模一樣是不會觸發重建索引的,如果將detect_noop=false不管內容有沒有變化都會重建索引,這一點可以通過version的值的變化來發現
更新的文檔,必須提前存在,除非你用upset+script來更新,否則會報document
missing異常
(二)script + upset更新方式:
java api
` HashMap params=new HashMap<>();
HashMap data=new HashMap<>();
data.put("name","12345");
params.put("source",data);
StringBuffer sb_json = new StringBuffer("ctx._source=source");
Script script = new Script(sb_json.toString(), ScriptService.ScriptType.INLINE, "groovy", params);
UpdateRequestBuilder urb= client.prepareUpdate("active2018-03-11", "active", "16");
urb.setScript(script);
urb.setUpsert(data);
urb.execute().actionGet();
System.out.println("更新完事。。。。。。 ");
curl
curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
"script" : {
"inline": "ctx._source.counter += count",
"params" : {
"count" : 4
}
},
"upsert" : {
"counter" : 1
}
}'
(三):scripted_upsert用法:
官網個的例子沒有跑通,下面這個是按照stackoverflow上面的例子改寫的,可以通過
在postman里面已經跑通:
首先是在post請求的url
java api:
` HashMap params=new HashMap<>();
HashMap data=new HashMap<>();
data.put("name","12345");
HashMap newdata=new HashMap<>();
newdata.put("name","789");
params.put("data",data);
params.put("newdata",newdata);
StringBuffer sb_json = new StringBuffer("if (ctx.op == \"create\") ctx._source=data; else ctx._source=newdata");
Script script = new Script(sb_json.toString(), ScriptService.ScriptType.INLINE, "groovy", params);
UpdateRequestBuilder urb= client.prepareUpdate("active2018-03-11", "active", "16");
urb.setScript(script);
urb.setScriptedUpsert(true);
urb.setUpsert("{}");//必須有這個值,否則會報document missing exception
urb.execute().actionGet();
System.out.println("更新完事。。。。。。 ");
curl方式
http://192.168.201.5:9200/active2018-03-11/active/11/_update
然后是下面的body里面選擇raw然類型是JSON(application/json):
{
"scripted_upsert":true,
"script" : {
"script":"if (ctx.op == \"create\") ctx._source=data; else ctx._source=newdata ",
"params" : {
"data":{
"ct":11,
"aid":"a22",
"tid":"t11"
},
"newdata":{
"ct":1000,
"aid":"a2qq2",
"tid":"qq"
}
}
},
"upsert" : {}
}
執行上面的腳本,首先會檢查索引是否存在,如果不存在就會新建一個索引,然后會判斷id等于11這條數據存在不存在,如果不存在就把data里面的數據作為第一次的插入數據,如果已經存在就會把原來的數據刪除掉然后把newdata的數據插入進去,可以理解就是更新。這里需要注意,如果用的是動態mapping,需要注意數據的類型,動態mapping下兩條數據里面的同一個字段可以擁有不同的類型,這樣既靈活又帶來了風險,所以對于嚴謹類型的數據推薦使用靜態mapping,嚴格限定字段的類型。
(四)doc_as_upsert方式:
這個方式其實就是前面兩個的簡潔版,意思就是沒有就插入有就覆蓋,注意這是是覆蓋并不是把原來的刪除在插入,而且如果是動態mapping還可以改變字段的類型,但不建議這么用。
java api:
` HashMap data=new HashMap<>();
data.put("name","234");
data.put("age",123);
data.put("address","北京海淀區");
UpdateRequestBuilder urb= client.prepareUpdate("active2018-03-11", "active", "16");
urb.setDoc(data);
urb.setDocAsUpsert(true);
urb.execute().actionGet();//
System.out.println("操作成功......");
curl方式:
http://192.168.201.5:9200/active2018-03-11/active/12/_update
{
"doc" : {
"name" : "6755",
"age":12,
"address":"北京朝陽"
},
"doc_as_upsert" : true
}
總結:
上面更新操作es幾種方法,總體來說使用script更新的方式最強大,可以做一些復雜業務場景的操作,如數值的累增或者操作集合對象元素的追加或者刪除,其他的幾種方式適合簡單的更新操作。
不管使用那種更新方式,我們都需要考慮并發問題,通過前面一系列的文章的介紹,我們知道es里面的更新,刪除,都是偽操作,尤其是更新,在es內部的實際處理流程是:
(1)查詢舊的document數據
(2)修改成最新的數據
(3)然后重建整條document
在這里的三個階段,如果同時又另外一個進程也在修改該條數據,就會發生沖突,es里面是根據version字段來判斷是否沖突的,在上面的步驟中的第一步查詢舊的數據會得到version字段,在第三步時候寫的時候會把這個version字段在傳回,這個時候如果發現version不一致就會發生沖突然后拋出異常,所以大家在使用的時候可以優先通過設計避免多線程操作,如果實在沒法避免則可以使用es里面的提供的version字段來通過樂觀鎖控制并發問題,如果操作是簡單的累加或累減還可以用更簡單的方法沖突重試來解決并發問題,一句話就是具體場景具體分析,關于es并發問題后面有空可以單獨再整理一篇文章出來。
總結
以上是生活随笔為你收集整理的es重建字段类型_关于elasticsearch中更新数据的几种方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html制作花样链接卡页面_使用HTML
- 下一篇: 空间刚架matlab_Matlab绘制空