實際工作中經常需要根據id查詳情,常規的可以用query的方式實現,這里記錄用 MultiGet 來實現的主要代碼。
壓測的初步感覺是 MultiGet 比用 query 更快,暫時還沒有做嚴謹的對比。
1. 創建 client
// endpoints如: 127.0.0.1:9200,127.0.0.1:9201 public RestHighLevelClient client() { try { // 解析 String[] ipAndPortList = endpoints.split(","); // 構造host HttpHost[] hosts = new HttpHost[ipAndPortList.length]; for (int i = 0; i < ipAndPortList.length; i++) { // 解析 String[] ipAndPort = ipAndPortList[i].split(":"); // 獲得ip String ip = ipAndPort[0]; // 獲得端口 String port = ipAndPort[1]; // 打印ip端口日志 logger.info("ES節點 : ip {},端口 {}", ip, port); // 獲取HttpHost實例 hosts[i] = new HttpHost(ip, Integer.parseInt(port), "http"); } // low builder RestClientBuilder builder = RestClient.builder(hosts); // 配置線程 builder.setHttpClientConfigCallback(httpClientBuilder -> { // 設置最大連接數 httpClientBuilder.setMaxConnTotal(200); // 設置每個route最大連接數 httpClientBuilder.setMaxConnPerRoute(200); return httpClientBuilder; }); // new client return new RestHighLevelClient(builder); } catch (Exception e) { // 打印異常 logger.error("Create RestHighLevelClient failed."); // 此時返回空 return null; } }
2. multi-get 獲取並解析數據
/** * multiGet 查詢 * * @param ids 多個id * @param tClass 類 * @param index 索引 */ public <T> PageEntity<T> multiGet(List<String> ids, Class<T> tClass, String index) throws IOException { // 參數非空校驗 if (esConfig.client() == null) { // 拋出不支持操作異常 throw new UnsupportedOperationException(); } // 構建 multi get MultiGetRequest request = new MultiGetRequest(); // 為每個 id 構建查詢語句 for (String id : ids) { // 為 id 添加查詢 request.add(new MultiGetRequest.Item(index, id)); } // 查詢 MultiGetResponse response = client().mget(request, RequestOptions.DEFAULT); // 結果解析 return parseMultiGetResponse(response, tClass); } /** * multiGet 查詢結果解析 * * @param response 查詢結果 * @param tClass T Class * @param <T> T * @return total size + list of T */ private <T> PageEntity<T> parseMultiGetResponse(MultiGetResponse response, Class<T> tClass) { MultiGetItemResponse[] itemResponses = response.getResponses(); // 結果解析 List<T> retList = new ArrayList<>(); // 解析 for (MultiGetItemResponse itemResponse : itemResponses) { // 判斷當前item獲取是否成功 if (itemResponse.getFailure() != null) { continue; } // 獲取響應結果 GetResponse getResponse = itemResponse.getResponse(); // 判斷結果是否存在 if (getResponse.isExists()) { // 獲得命中的信息 String sourceAsString = getResponse.getSourceAsString(); // 解析命中的信息 T t = JSON.parseObject(sourceAsString, tClass); // 添加到結果集 retList.add(t); } } // 返回結果容器 PageEntity<T> pageEntity = new PageEntity<>(); // 保存retList pageEntity.setResult(retList); // 保存總數 pageEntity.setTotalSize((long) retList.size()); // 返回結果 return pageEntity; }
其中,PageEntity的定義如下
@Data public class PageEntity<T> { private List<T> result; private Long totalSize; }