今日閱讀公司一套資料加工中間工具的原始碼,檢視es操作中的update操作。其中方法命名為updateOrInsert。但是沒見到程式碼中有ES的insert方法呼叫。於是仔細分析了程式碼邏輯。
經過一路追溯,直至ES java客戶端請求傳送程式碼。沒找到insert相關內容。
於是到官網檢視究竟,可官網對 java Client相關說明比較少。檢視不到具體api的說明。於是回到程式碼呼叫處:
String jsonText = jsonBuild.endObject().string();
UpdateRequest request = (UpdateRequest)esClient.prepareUpdate(xxx.getDatabase(), xxx.getTable(), docId).setDoc(jsonText).setDetectNoop(true).setDocAsUpsert(true).setRetryOnConflict(this.retryOnConflict).request();
esClient.update(request).get();
程式碼中屬於鏈式呼叫,由於太長沒有換行,竟然沒看到後邊的setDetectNoop,setDocAsUpsert引數的呼叫,於是思考,javaClient不就是封裝和轉換了呼叫請求麼,於是再回到官網檢視Document APIs,找到update操作的說明,就有了下邊關於 Detecting Noop Updates 以及 Upserts說明:
Detecting noop updatesedit
If
doc
is specified its value is merged with the existing_source
. By default the document is only reindexed if the new_source
field differs from the old. Settingdetect_noop
tofalse
will cause Elasticsearch to always update the document even if it hasn’t changed. For example:curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{ "doc" : { "name" : "new_name" }, "detect_noop": false }'
上邊這段的意思是當更新的文件發生變化時進行更新,如果為fasle,則始終更新。
Upsertsedit
If the document does not already exist, the contents of the
upsert
element will be inserted as a new document. If the document does exist, then thescript
will be executed instead:curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{ "script" : { "inline": "ctx._source.counter += count", "params" : { "count" : 4 } }, "upsert" : { "counter" : 1 } }'
scripted_upsert
editIf you would like your script to run regardless of whether the document exists or not — i.e. the script handles initializing the document instead of the
upsert
element — then setscripted_upsert
totrue
:curl -XPOST 'localhost:9200/sessions/session/dh3sgudg8gsrgl/_update' -d '{ "scripted_upsert":true, "script" : { "id": "my_web_session_summariser", "params" : { "pageViewEvent" : { "url":"foo.com/bar", "response":404, "time":"2014-01-01 12:32" } } }, "upsert" : {} }'
doc_as_upsert
editInstead of sending a partial
doc
plus anupsert
doc, settingdoc_as_upsert
totrue
will use the contents ofdoc
as theupsert
value:curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{ "doc" : { "name" : "new_name" }, "doc_as_upsert" : true }'
上邊描述:upsert引數的使用,有三種方式:
- 指定upsert內容
- 指定開啟指令碼upsert開關使用指令碼處理upsert
- 使用文件內容做為upsert引數,則開啟 doc_as_upsert。顯然我們上邊所說的javaClient呼叫中就是使用的 doc_as_upsert,這樣當文件不存在時候,就會將傳遞過來的文件內容insert進去。達到update or Insert 目的。
因此對於ES java Clent使用不熟的完全可以參照 api命名查詢官網的 api說明,java客戶端只不過是用java語言進行了封裝。一看便知道呼叫程式碼邏輯的含義了。僅此記錄,為不熟悉ES的其他使用者 引個路子。
官網內容連結:https://www.elastic.co/guide/en/elasticsearch/reference/2.1/docs-update.html#upserts
可以根據自己使用的ES版本進行切換檢視。