標籤:class current 建構函式 lan 不為 new extern listener style
multiGet API並行地在單個http請求中執行多個get請求。
Multi-Get Request
MultiGetRequest建構函式為空白,需要你添加`MultiGetRequest.Item`來配置要擷取的內容:
MultiGetRequest request = new MultiGetRequest(); request.add(new MultiGetRequest.Item( "index", // Index "type", // Type "example_id")); //Document id //再添加一個 request.add(new MultiGetRequest.Item("index", "type", "another_id"));
選擇性參數
get API支援的選擇性參數,multiGet都支援。 您可以在每一項上設定這些大部分選擇性參數,為什麼是大部分,因為有的參數是設定在主請求上,而不是每一項上:
//禁止擷取source,預設為啟用 request.add(new MultiGetRequest.Item("index", "type", "example_id") .fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE));
配置source包含指定的欄位:
String[] includes = new String[] {"foo", "*r"}; String[] excludes = Strings.EMPTY_ARRAY; FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes); request.add(new MultiGetRequest.Item("index", "type", "example_id") .fetchSourceContext(fetchSourceContext));
配置source排除指定的欄位:
String[] includes1 = Strings.EMPTY_ARRAY; String[] excludes1 = new String[] {"foo", "*r"}; FetchSourceContext fetchSourceContext1 = new FetchSourceContext(true, includes, excludes); request.add(new MultiGetRequest.Item("index", "type", "example_id") .fetchSourceContext(fetchSourceContext1));
//配置擷取指定的stored欄位,要求欄位在mappings中是分開儲存的(stored儲存的原始欄位,未經過分詞的) request.add(new MultiGetRequest.Item("index", "type", "example_id") .storedFields("foo")); MultiGetResponse response = client.multiGet(request); MultiGetItemResponse item = response.getResponses()[0]; //擷取foo的stored欄位,要求欄位和mappings中是分開儲存的 String value = item.getResponse().getField("foo").getValue();
// Routing value request.add(new MultiGetRequest.Item("index", "type", "with_routing") .routing("some_routing")); // Parent value request.add(new MultiGetRequest.Item("index", "type", "with_parent") .parent("some_parent")); request.add(new MultiGetRequest.Item("index", "type", "with_version") .versionType(VersionType.EXTERNAL)// Version type .version(10123L));//Version
preference, realtime 和 refresh可以設定在主請求上,而不能設定在每項上
request.preference("some_preference");//preference值 request.realtime(false);//將realtime標誌設定為false(預設為true) request.refresh(true);//在檢索文檔之前執行重新整理(預設為false)
同步執行
//構建MultiGetRequest後,您可以用multiGet來同步執行: MultiGetResponse response1 = client.multiGet(request);
非同步執行
非同步執行多個get請求需要將MultiGetRequest執行個體和ActionListener執行個體傳遞給非同步方法呼叫:
client.multiGetAsync(request, listener); //當MultiGetRequest執行完成時,ActionListener將被調用。
非同步方法呼叫不會阻塞並會立即返回。 一旦請求完成,如果執行成功完成,則使用onResponse方法回調ActionListener,如果失敗則使用onFailure方法。
MultiGetResponse的典型監聽器如下所示:
ActionListener<MultiGetResponse> listener = new ActionListener<MultiGetResponse>() { @Override public void onResponse(MultiGetResponse response) { //執行成功完成時調用。 response以參數的形式提供。 } @Override public void onFailure(Exception e) { // 在失敗的情況下調用。 引發的異常作為參數提供。 } };Multi Get Response
返回的MultiGetResponse在getResponses中包含一個MultiGetItemResponse的列表,其順序與請求的順序相同。 如果擷取成功,MultiGetItemResponse包含GetResponse,如果失敗則包含MultiGetResponse.Failure。 成功看起來就像普通的GetResponse。
MultiGetItemResponse firstItem = response.getResponses()[0]; //assertNull(firstItem.getFailure());//getFailure返回null,由於這沒有失敗。 GetResponse firstGet = firstItem.getResponse();//getResponse返回GetResponse。 String index = firstItem.getIndex(); String type = firstItem.getType(); String id = firstItem.getId(); if (firstGet.isExists()) { long version = firstGet.getVersion(); String sourceAsString = firstGet.getSourceAsString();//以字串形式擷取文檔 Map<String, Object> sourceAsMap = firstGet.getSourceAsMap();//以Map <String,Object>形式擷取文檔 byte[] sourceAsBytes = firstGet.getSourceAsBytes();//以位元組數組的形式檢索文檔 } else { //處理未找到文檔的方案。 請注意,雖然返回的響應具有404狀態碼,但仍返回有效GetResponse而不是拋出異常。 //此時此類響應不持有任何來源文件,並且其isExists方法返回false。 }
當其中一個子請求執行不存在的索引時,getFailure將包含異常:
MultiGetItemResponse missingIndexItem = response.getResponses()[0]; assertNull(missingIndexItem.getResponse());//getResponse 是 null. //getFailure不為null,並且包含Exception,該異常實際上是一個ElasticsearchException Exception e = missingIndexItem.getFailure().getFailure(); ElasticsearchException ee = (ElasticsearchException) e; // TODO status is broken! fix in a followup //此時它的狀態為NOT_FOUND。 要不是這是一個multi get,它其實就是一個HTTP 404。 assertEquals(RestStatus.NOT_FOUND, ee.status()); //getMessage解釋了實際原因,沒有這樣的索引。 assertThat(e.getMessage(),containsString("reason=no such index"));
如果請求特定文檔版本,並且現有文檔具有不同的版本號碼,則會引發版本衝突:
MultiGetRequest request2 = new MultiGetRequest(); request2.add(new MultiGetRequest.Item("index", "type", "example_id") .version(1000L)); MultiGetResponse response2 = client.multiGet(request2); MultiGetItemResponse item2 = response.getResponses()[0]; assertNull(item.getResponse());//getResponse 是 null. //getFailure不為null,並且包含Exception,該異常實際上是一個ElasticsearchException Exception e = item.getFailure().getFailure(); ElasticsearchException ee = (ElasticsearchException) e; // TODO status is broken! fix in a followup //此時它的狀態為NOT_FOUND。 要不是這是一個multi get,它就是一個HTTP 409 。 // assertEquals(RestStatus.CONFLICT, ee.status()); //getMessage解釋了實際原因,即版本衝突。 assertThat(e.getMessage(), containsString("version conflict, current version [1] is " + "different than the one provided [1000]"));
官方文檔:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-multi-get.html
Multi-Get API