日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

es重建字段类型_关于elasticsearch中更新数据的几种方式

發(fā)布時間:2025/3/21 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 es重建字段类型_关于elasticsearch中更新数据的几种方式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

作為一個成熟的框架,Elasticsearch里面提供了豐富的操作數(shù)據(jù)的api,本篇我們就來學習一下在es中更新數(shù)據(jù)的幾種方式。

(一)更新文檔

(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......");

注意部分更新功能,前提是索引和該條數(shù)據(jù)已經(jīng)存在,否則會拋出對應的異常,只要任何一個不滿足,都會更新失敗。

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存在不同的字段情況下才會重建索引,如果一模一樣是不會觸發(fā)重建索引的,如果將detect_noop=false不管內(nèi)容有沒有變化都會重建索引,這一點可以通過version的值的變化來發(fā)現(xiàn)

更新的文檔,必須提前存在,除非你用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用法:

官網(wǎng)個的例子沒有跑通,下面這個是按照stackoverflow上面的例子改寫的,可以通過

在postman里面已經(jīng)跑通:

首先是在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" : {}

}

執(zhí)行上面的腳本,首先會檢查索引是否存在,如果不存在就會新建一個索引,然后會判斷id等于11這條數(shù)據(jù)存在不存在,如果不存在就把data里面的數(shù)據(jù)作為第一次的插入數(shù)據(jù),如果已經(jīng)存在就會把原來的數(shù)據(jù)刪除掉然后把newdata的數(shù)據(jù)插入進去,可以理解就是更新。這里需要注意,如果用的是動態(tài)mapping,需要注意數(shù)據(jù)的類型,動態(tài)mapping下兩條數(shù)據(jù)里面的同一個字段可以擁有不同的類型,這樣既靈活又帶來了風險,所以對于嚴謹類型的數(shù)據(jù)推薦使用靜態(tài)mapping,嚴格限定字段的類型。

(四)doc_as_upsert方式:

這個方式其實就是前面兩個的簡潔版,意思就是沒有就插入有就覆蓋,注意這是是覆蓋并不是把原來的刪除在插入,而且如果是動態(tài)mapping還可以改變字段的類型,但不建議這么用。

java api:

` HashMap data=new HashMap<>();

data.put("name","234");

data.put("age",123);

data.put("address","北京海淀區(qū)");

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更新的方式最強大,可以做一些復雜業(yè)務場景的操作,如數(shù)值的累增或者操作集合對象元素的追加或者刪除,其他的幾種方式適合簡單的更新操作。

不管使用那種更新方式,我們都需要考慮并發(fā)問題,通過前面一系列的文章的介紹,我們知道es里面的更新,刪除,都是偽操作,尤其是更新,在es內(nèi)部的實際處理流程是:

(1)查詢舊的document數(shù)據(jù)

(2)修改成最新的數(shù)據(jù)

(3)然后重建整條document

在這里的三個階段,如果同時又另外一個進程也在修改該條數(shù)據(jù),就會發(fā)生沖突,es里面是根據(jù)version字段來判斷是否沖突的,在上面的步驟中的第一步查詢舊的數(shù)據(jù)會得到version字段,在第三步時候?qū)懙臅r候會把這個version字段在傳回,這個時候如果發(fā)現(xiàn)version不一致就會發(fā)生沖突然后拋出異常,所以大家在使用的時候可以優(yōu)先通過設計避免多線程操作,如果實在沒法避免則可以使用es里面的提供的version字段來通過樂觀鎖控制并發(fā)問題,如果操作是簡單的累加或累減還可以用更簡單的方法沖突重試來解決并發(fā)問題,一句話就是具體場景具體分析,關于es并發(fā)問題后面有空可以單獨再整理一篇文章出來。

總結

以上是生活随笔為你收集整理的es重建字段类型_关于elasticsearch中更新数据的几种方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。