Elasticsearch 6.4基本操作 - Java版
1. Elasticsearch Java API有四類client連接方式
- TransportClient
- RestClient
- Jest
- Spring Data Elasticsearch
其中TransportClient和RestClient是Elasticsearch原生的api。TransportClient可以支持2.x,5.x版本,TransportClient將會在Elasticsearch 7.0棄用並在8.0中完成刪除,替而代之,我們使用Java High Level REST Client,它使用HTTP請求而不是Java序列化請求。
Jest是Java社區開發的,是Elasticsearch的Java Http Rest客戶端;Spring Data Elasticsearch是spring集成的Elasticsearch開發包。
建議:TransportClient將會在後面的版本中棄用,因此不推薦後續使用;而Jest由於是社區維護,所以更新有一定延遲,目前最新版對接ES6.3.1,近一個月只有四個issue,說明整體活躍度較低,因此也不推薦使用;Spring Data Elasticsearch主要是與Spring生態對接,可以在web系統中整合到Spring中使用。目前比較推薦使用官方的高階、低階Rest Client,官方維護,比較值得信賴。本文主要介紹RestClient,其他的只做簡單概述。
1.1 TransportClient
這裏考慮到後面版本將棄用TransportClinet,主要簡單介紹TransportClient的創建、以及一些基本增刪改查操作。
<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>6.4.3</version> </dependency> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>6.4.3</version> </dependency>
/** * @Author: Yang JianQiu * @Date: 2018/11/12 16:40 * * transportClient將會在7.0版本上過時,並在8.0版本上移除掉,建議使用Java High Level REST Client */ public class TransportClientUtils { private TransportClient client = null; /** * 這裏使用餓漢單例模式創建TransportClient */ public TransportClientUtils() { if (client == null){ synchronized (TransportClientUtils.class){ if (client == null){ client = getClient(); } } } } public TransportClient getClient(){ TransportClient client = null; try { Settings settings = Settings.builder() .put("client.transport.sniff", true) .put("cluster.name", "bigdata").build(); client = new PreBuiltTransportClient(settings) .addTransportAddress(new TransportAddress(new InetSocketAddress("192.168.187.201", 9300))); } catch (Exception e) { e.printStackTrace(); } return client; } public viod test(){ //增,插入記錄 IndexResponse response = client.prepareIndex("twitter", "_doc") .setSource(json, XContentType.JSON) .get(); //根據Id查詢 GetResponse response = client.prepareGet("twitter", "_doc", 1).get(); //根據Id刪除 DeleteResponse response = client.prepareDelete("twitter", "_doc", 1).get(); //根據Id更新對應的字段 UpdateRequest updateRequest1 = new UpdateRequest("twitter", "_doc", "NpEWCGcBi36MQkKOSdf3") .doc(jsonBuilder() .startObject() .field("user", "tom") .endObject() ); client.update(updateRequest1).get(); //另外還有批處理API、search負責查詢API、Aggregate聚合API... } }
具體的TransportClient的其他API應用可以參考Elasticsearch的TransportClient API doc:
https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/index.html
1.2 Rest Client
Rest Client分為Java Low REST Client和Java High Level REST Client。
maven的依賴包:
<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>6.4.3</version> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> <version>6.4.3</version> </dependency> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>6.4.3</version> </dependency>
RestHighLevelClient與RestClient的創建:
/** * @author: Swordfall Yeung * @date: * @desc: */ public class RestClientUtils { /** * 高階Rest Client */ private RestHighLevelClient client = null; /** * 低階Rest Client */ private RestClient restClient = null; /** * 這裏使用餓漢單例模式創建RestHighLevelClient */ public RestClientUtils() { if (client == null) { synchronized (RestHighLevelClient.class) { if (client == null) { client = getClient(); } } } } private RestHighLevelClient getClient() { RestHighLevelClient client = null; try { client = new RestHighLevelClient( RestClient.builder( new HttpHost("192.168.187.201", 9300, "http") ) ); } catch (Exception e) { e.printStackTrace(); } return client; } private RestClient getRestClient() { RestClient client = null; try { client = RestClient.builder( new HttpHost("192.168.187.201", 9300, "http") ).build(); } catch (Exception e) { e.printStackTrace(); } return client; } public void closeClient() { try { if (client != null) { client.close(); } } catch (IOException e) { e.printStackTrace(); } } /** * document API 主要是些簡單的增刪改查操作 */ public void documentAPI() { //... } /** * Search API 主要是些復雜查詢操作 */ public void searchAPI() { //... } }
RestHighLevelAPI分為Document APIs、Search APIs、Miscellaneous APIs、Indices APIs、Cluster APIs...等等,這裏主要介紹常用的Document APIs和Search APIs,其余的APIs可以參考:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html
1.2.1 Document APIs
Document APIs主要涉及些增刪改查等操作,包括Single document APIs單條操作和Multi-document APIs批量操作。Document APIs均可以設置可選參數,實現同步、異步,也均可拋出異常,這裏以Index API為例,後面的不再簡述。
Index API介紹:
/** * 增,插入記錄 * 插入操作有四種方式,分同步異步操作,可選參數設置,結果返回IndexResponse,拋出異常 * @throws Exception */ public void index() throws Exception{ //第一種方式: String IndexRequest request = new IndexRequest("posts", "doc", "1"); String jsonString = "{" + "\"user\":\"kimchy\"," + "\"postDate\":\"2013-01-30\"," + "\"message\":\"trying out Elasticsearch\"" + "}"; request.source(jsonString, XContentType.JSON); //第二種方式: Map Map<String, Object> jsonMap = new HashMap<>(); jsonMap.put("user", "kimchy"); jsonMap.put("postDate", new Date()); jsonMap.put("message", "trying out Elasticsearch"); IndexRequest indexRequest = new IndexRequest("posts", "doc", "1").source(jsonMap); //第三種方式: XContentBuilder automatically converted to JSON XContentBuilder builder = XContentFactory.jsonBuilder(); builder.startObject(); { builder.field("user", "kimchy"); builder.timeField("postDate" , new Date()); builder.field("message", "trying out Elasticsearch"); } builder.endObject(); IndexRequest indexRequest1 = new IndexRequest("posts", "doc", "1") .source(builder); //第四種方式: source -> key-pairs IndexRequest indexRequest2 = new IndexRequest("posts", "doc", "1") .source("user", "kimchy", "postDate", new Date(), "message", "trying out Elasticsearch" ); //可選的參數設置 request.routing("routing"); request.parent("parent"); request.timeout(TimeValue.timeValueSeconds(1)); request.timeout("1s"); request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL); request.setRefreshPolicy("wait_for"); request.version(2); request.versionType(VersionType.EXTERNAL); request.opType(DocWriteRequest.OpType.CREATE); request.opType("create"); request.setPipeline("pipeline"); //同步執行 IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT); //異步執行 ActionListener<IndexResponse> listener = new ActionListener<IndexResponse>() { @Override public void onResponse(IndexResponse indexResponse) { } @Override public void onFailure(Exception e) { } }; client.indexAsync(request, RequestOptions.DEFAULT, listener); //Index Response String index = indexResponse.getIndex(); String type = indexResponse.getType(); String id = indexResponse.getId(); long version = indexResponse.getVersion(); //拋出異常 IndexRequest request1 = new IndexRequest("posts", "doc", "1") .source("field", "value") .version(1); try { IndexResponse response = client.index(request, RequestOptions.DEFAULT); } catch (ElasticsearchException e) { if (e.status() == RestStatus.CONFLICT){ } } }
Get API介紹
/** * 根據 id 獲取數據 * @throws Exception */ public void get() throws Exception{ GetRequest request = new GetRequest("posts", "doc", "1"); //可選參數設置 request.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE); String[] includes = new String[]{"message", "*Date"}; String[] excludes = Strings.EMPTY_ARRAY; FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes); request.fetchSourceContext(fetchSourceContext); //同步執行 GetResponse getResponse = client.get(request, RequestOptions.DEFAULT); //異步執行 listener的寫法參照Index的異步執行的listener client.getAsync(request, RequestOptions.DEFAULT, listener); //Get Response 獲取信息 //拋出異常 }
Exists API介紹
/** * 是否存在 * @throws Exception */ public void exists() throws Exception{ GetRequest getRequest = new GetRequest("posts", "doc", "1"); getRequest.fetchSourceContext(new FetchSourceContext(false)); getRequest.storedFields("_none_"); //同步執行 boolean exists = client.exists(getRequest, RequestOptions.DEFAULT); //異步執行 listener的寫法參照Index的 client.existsAsync(getRequest, RequestOptions.DEFAULT, listener); if (exists){ System.out.println("存在"); }else { System.out.println("不存在"); } }
Delete API介紹
/** * 根據id刪除 * @throws Exception */ public void delete() throws Exception{ DeleteRequest request = new DeleteRequest("posts", "doc", "1"); //同步執行 DeleteResponse deleteResponse = client.delete(request, RequestOptions.DEFAULT); //異步執行 listener參照index的 client.deleteAsync(request, RequestOptions.DEFAULT, listener); //Delete Response String index = deleteResponse.getIndex(); // document was not found if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) { } //拋出異常 }
Update API介紹
/** * 根據id更新 * @throws Exception */ public void update() throws Exception{ UpdateRequest request = new UpdateRequest("posts", "doc", "1"); Map<String, Object> parameters = Collections.singletonMap("count", 4); //第一種方式:inline script Script inline = new Script(ScriptType.INLINE, "painless", "ctx._source.field += params.count", parameters); request.script(inline); //第二種方式:stored script Script stored = new Script(ScriptType.STORED, null, "increment-field", parameters); request.script(stored); //第三種方式:partial document String String jsonString = "{" + "\"updated\":\"2017-01-01\"," + "\"reason\":\"daily update\"" + "}"; request.doc(jsonString, XContentType.JSON); //第四種方式:partial document Map Map<String, Object> jsonMap = new HashMap<>(); jsonMap.put("updated", new Date()); jsonMap.put("reason", "daily update"); request.doc(jsonMap); //第五種方式:partial document XContentBuilder XContentBuilder builder = XContentFactory.jsonBuilder(); builder.startObject(); { builder.timeField("updated", new Date()); builder.field("reason", "daily update"); } builder.endObject(); request.doc(builder); //第六種方式:partial document Object key-pairs request.doc("updated", new Date(), "reason", "daily update"); //upserts String jsonString1 = "{\"created\":\"2017-01-01\"}"; request.upsert(jsonString1, XContentType.JSON); //同步執行 UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT); //異步執行, listener創建參考index的 client.updateAsync(request, RequestOptions.DEFAULT, listener); //update Response GetResult result = updateResponse.getGetResult(); if (result.isExists()) { String sourceAsString = result.sourceAsString(); Map<String, Object> sourceAsMap = result.sourceAsMap(); byte[] sourceAsBytes = result.source(); } else { } //拋出異常 }
Bulk API介紹
/** * 批量處理 * @throws Exception */ public void bulk() throws Exception{ BulkRequest request = new BulkRequest(); //Other request.add(new DeleteRequest("posts", "doc", "3")); request.add(new UpdateRequest("posts", "doc", "2") .doc(XContentType.JSON, "other", "test")); request.add(new IndexRequest("posts", "doc", "4") .source(XContentType.JSON, "field", "baz")); //同步執行 BulkResponse bulkResponses = client.bulk(request, RequestOptions.DEFAULT); //異步執行 ActionListener<BulkResponse> listener = new ActionListener<BulkResponse>() { @Override public void onResponse(BulkResponse bulkResponse) { } @Override public void onFailure(Exception e) { } }; client.bulkAsync(request, RequestOptions.DEFAULT, listener); //Bulk Response 批處理結果 for (BulkItemResponse bulkItemResponse: bulkResponses){ DocWriteResponse itemResponse = bulkItemResponse.getResponse(); if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.INDEX || bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE) { IndexResponse indexResponse = (IndexResponse) itemResponse; } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.UPDATE) { UpdateResponse updateResponse = (UpdateResponse) itemResponse; } else if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.DELETE) { DeleteResponse deleteResponse = (DeleteResponse) itemResponse; } } for (BulkItemResponse bulkItemResponse : bulkResponses) { if (bulkItemResponse.isFailed()) { BulkItemResponse.Failure failure = bulkItemResponse.getFailure(); } } //Bulk Processor 自定義批處理器 BulkProcessor.Listener listener1 = new BulkProcessor.Listener() { @Override public void beforeBulk(long l, BulkRequest bulkRequest) { } @Override public void afterBulk(long l, BulkRequest bulkRequest, BulkResponse bulkResponse) { } @Override public void afterBulk(long l, BulkRequest bulkRequest, Throwable throwable) { } }; BiConsumer<BulkRequest, ActionListener<BulkResponse>> bulkConsumer = (request1, bulkListener) -> client.bulkAsync(request1, RequestOptions.DEFAULT, bulkListener); BulkProcessor bulkProcessor = BulkProcessor.builder(bulkConsumer, listener1).build(); BiConsumer<BulkRequest, ActionListener<BulkResponse>> bulkConsumer1 = (request2, bulkListener) -> client.bulkAsync(request2, RequestOptions.DEFAULT, bulkListener); BulkProcessor.Builder builder = BulkProcessor.builder(bulkConsumer1, listener1); builder.setBulkActions(500); builder.setBulkSize(new ByteSizeValue(1L, ByteSizeUnit.MB)); builder.setConcurrentRequests(0); builder.setFlushInterval(TimeValue.timeValueSeconds(10L)); builder.setBackoffPolicy(BackoffPolicy .constantBackoff(TimeValue.timeValueSeconds(1L), 3)); //Once the BulkProcessor is created requests can be added to it: IndexRequest one = new IndexRequest("posts", "doc", "1"). source(XContentType.JSON, "title", "In which order are my Elasticsearch queries executed?"); IndexRequest two = new IndexRequest("posts", "doc", "2") .source(XContentType.JSON, "title", "Current status and upcoming changes in Elasticsearch"); IndexRequest three = new IndexRequest("posts", "doc", "3") .source(XContentType.JSON, "title", "The Future of Federated Search in Elasticsearch"); bulkProcessor.add(one); bulkProcessor.add(two); bulkProcessor.add(three); boolean terminated = bulkProcessor.awaitClose(30L, TimeUnit.SECONDS); }
Multi-Get API介紹
/** * 根據id批量獲取數據 * @throws Exception */ public void multiGet() throws Exception{ MultiGetRequest request = new MultiGetRequest(); request.add(new MultiGetRequest.Item("index","type","example_id")); request.add(new MultiGetRequest.Item("index", "type", "another_id")); //optional arguments request.add(new MultiGetRequest.Item("index", "type", "example_id") .fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE)); //同步執行 MultiGetResponse responses = client.mget(request, RequestOptions.DEFAULT); //異步執行 listener參考Index的 client.mgetAsync(request, RequestOptions.DEFAULT, listener); //Multi Get Response MultiGetItemResponse firstItem = response.getResponses()[0]; GetResponse firstGet = firstItem.getResponse(); if (firstGet.isExists()) { } }
1.2.2 Search APIs
public void search() throws Exception{ //match all query 查詢所有數據 SearchRequest searchRequest = new SearchRequest(); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchAllQuery()); searchRequest.source(searchSourceBuilder); //使用SearchSourceBuilder查詢指定字段 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.query(QueryBuilders.termQuery("user", "kimchy")); sourceBuilder.from(0); sourceBuilder.size(5); sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); SearchRequest searchRequest2 = new SearchRequest(); //index 數據庫 searchRequest2.indices("posts"); searchRequest2.source(sourceBuilder); //Building queries //One way, QueryBuilder can be created using its constructor 使用QueryBuilder的構造函數 MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("user", "kimchy"); matchQueryBuilder.fuzziness(Fuzziness.AUTO); matchQueryBuilder.prefixLength(3); matchQueryBuilder.maxExpansions(10); //Two way, QueryBuilder objects can also be created using the QueryBuilders utility class. 直接使用matchQuery QueryBuilder matchQueryBuilder1 = matchQuery("user", "kimchy") .fuzziness(Fuzziness.AUTO) .prefixLength(3) .maxExpansions(10); searchSourceBuilder.query(matchQueryBuilder1); //Specifying Sorting 指定排序 sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC)); sourceBuilder.sort(new FieldSortBuilder("_uid").order(SortOrder.ASC)); //Source filtering, turn off _source retrieval completely sourceBuilder.fetchSource(false); //an array of one or more wildcard patterns to control which fields get included or excluded in a more fine grained way String[] includeFields = new String[] {"title", "user", "innerObject.*"}; String[] excludeFields = new String[] {"_type"}; sourceBuilder.fetchSource(includeFields, excludeFields); //Requesting Aggregations SearchSourceBuilder searchSourceBuilder2 = new SearchSourceBuilder(); TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_company") .field("company.keyword"); aggregation.subAggregation(AggregationBuilders.avg("average_age") .field("age")); searchSourceBuilder2.aggregation(aggregation); //Requesting Suggestions SearchSourceBuilder searchSourceBuilder3 = new SearchSourceBuilder(); SuggestionBuilder termSuggestionBuilder = SuggestBuilders.termSuggestion("user").text("kmichy"); SuggestBuilder suggestBuilder = new SuggestBuilder(); suggestBuilder.addSuggestion("suggest_user", termSuggestionBuilder); searchSourceBuilder3.suggest(suggestBuilder); //同步執行 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); //異步執行 listener參考index的 client.searchAsync(searchRequest, RequestOptions.DEFAULT, listener); //SearchResponse RestStatus status = searchResponse.status(); for (ShardSearchFailure failure : searchResponse.getShardFailures()) { // failures should be handled here } //Retrieving SearchHits 獲取結果數據 SearchHits hits = searchResponse.getHits(); long totalHits = hits.getTotalHits(); float maxScore = hits.getMaxScore(); SearchHit[] searchHits = hits.getHits(); for (SearchHit hit : searchHits) { // do something with the SearchHit String index = hit.getIndex(); String type = hit.getType(); String id = hit.getId(); float score = hit.getScore(); String sourceAsString = hit.getSourceAsString(); Map<String, Object> sourceAsMap = hit.getSourceAsMap(); String documentTitle = (String) sourceAsMap.get("title"); List<Object> users = (List<Object>) sourceAsMap.get("user"); Map<String, Object> innerObject = (Map<String, Object>) sourceAsMap.get("innerObject"); } //Retrieving Aggregations Aggregations aggregations = searchResponse.getAggregations(); Terms byCompanyAggregation = aggregations.get("by_company"); Terms.Bucket elasticBucket = byCompanyAggregation.getBucketByKey("Elastic"); Avg averageAge = elasticBucket.getAggregations().get("average_age"); double avg = averageAge.getValue(); Range range = aggregations.get("by_company"); Map<String, Aggregation> aggregationMap = aggregations.getAsMap(); Terms companyAggregation = (Terms) aggregationMap.get("by_company"); List<Aggregation> aggregationList = aggregations.asList(); for (Aggregation agg : aggregations) { String type = agg.getType(); if (type.equals(TermsAggregationBuilder.NAME)) { Terms.Bucket elasticBucket1 = ((Terms) agg).getBucketByKey("Elastic"); long numberOfDocs = elasticBucket1.getDocCount(); } } //Retrieving Suggestions Suggest suggest = searchResponse.getSuggest(); TermSuggestion termSuggestion = suggest.getSuggestion("suggest_user"); for (TermSuggestion.Entry entry : termSuggestion.getEntries()) { for (TermSuggestion.Entry.Option option : entry) { String suggestText = option.getText().string(); } } }
Multi-search APIs介紹:
public void multiSearch() throws Exception{ MultiSearchRequest request = new MultiSearchRequest(); SearchRequest firstSearchRequest = new SearchRequest(); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchQuery("user", "kimchy")); firstSearchRequest.source(searchSourceBuilder); request.add(firstSearchRequest); SearchRequest secondSearchRequest = new SearchRequest(); searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchQuery("user", "luca")); secondSearchRequest.source(searchSourceBuilder); request.add(secondSearchRequest); //同步執行 MultiSearchResponse response = client.msearch(request, RequestOptions.DEFAULT); //同步執行 listener參考index的 client.msearchAsync(request, RequestOptions.DEFAULT, listener); //MultiSearchResponse MultiSearchResponse.Item firstResponse = response.getResponses()[0]; SearchResponse searchResponse = firstResponse.getResponse(); MultiSearchResponse.Item secondResponse = response.getResponses()[1]; searchResponse = secondResponse.getResponse(); }
SearchTemplate APIs介紹:
/** * 查詢模板 * @throws Exception */ public void searchTemplate() throws Exception{ SearchTemplateRequest request = new SearchTemplateRequest(); request.setRequest(new SearchRequest("posts")); //Inline Templates request.setScriptType(ScriptType.INLINE); //instead of providing an inline script request.setScriptType(ScriptType.STORED); request.setScript( "{" + " \"query\": { \"match\": { \"{{ field }}\": \"{{ value }}\" } }," + " \"size\": \"{{ size }}\"" + "}"); Map<String, Object> scriptParams = new HashMap<>(); scriptParams.put("field", "title"); scriptParams.put("value", "elasticsearch"); scriptParams.put("size", 5); request.setScriptParams(scriptParams); //同步執行 SearchTemplateResponse response = client.searchTemplate(request, RequestOptions.DEFAULT); //異步執行 listener參考Index的 client.searchTemplateAsync(request, RequestOptions.DEFAULT, listener); //SearchTemplate Response SearchResponse searchResponse = response.getResponse(); BytesReference source = response.getSource(); }
Multi-SearchTemplate APIs介紹:
/** * 多個查詢模板執行 * @throws Exception */ public void MultiSearchTemplate() throws Exception{ String[] searchTerms = {"elasticsearch", "logstash", "kibana"}; MultiSearchTemplateRequest multiRequest = new MultiSearchTemplateRequest(); for (String searchTerm: searchTerms) { SearchTemplateRequest request = new SearchTemplateRequest(); request.setRequest(new SearchRequest("posts")); request.setScriptType(ScriptType.INLINE); request.setScript( "{" + " \"query\": { \"match\": { \"{{field}}\": \"{{value}}\" }}," + " \"size\": \"{{size}}\"" + "}" ); Map<String, Object> scriptParams = new HashMap<>(); scriptParams.put("field", "title"); scriptParams.put("value", searchTerm); scriptParams.put("size", 5); request.setScriptParams(scriptParams); multiRequest.add(request); } //同步執行 MultiSearchTemplateResponse multiResponse = client.msearchTemplate(multiRequest, RequestOptions.DEFAULT); //異步執行 ActionListener<MultiSearchTemplateResponse> listener = new ActionListener<MultiSearchTemplateResponse>() { @Override public void onResponse(MultiSearchTemplateResponse response) { } @Override public void onFailure(Exception e) { } }; client.msearchTemplateAsync(multiRequest, RequestOptions.DEFAULT, listener); //MultiSearchTemplateResponse for (MultiSearchTemplateResponse.Item item : multiResponse.getResponses()) { if (item.isFailure()) { String error = item.getFailureMessage(); } else { SearchTemplateResponse searchTemplateResponse = item.getResponse(); SearchResponse searchResponse = searchTemplateResponse.getResponse(); searchResponse.getHits(); } } }
其余APIs可以參考:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html
1.3 Jest
Jest是第三方工具,是ElasticSearch的Java HTTP Rest客戶端。Jest填補了ElasticSearch缺少Http Rest接口客戶端的空白。
Jest的API為:
Jest的具體用法參考:https://blog.csdn.net/u010466329/article/details/75020956/
Jest的代碼github地址:https://github.com/searchbox-io/Jest
1.4 Spring Data Elasticsearch
可參考https://blog.csdn.net/qq_33314107/article/details/80725994
2. 常見報錯
NoNodeAvailableException報錯,主要是外網IP沒有配置
在elasticSearch.yml上配置transport.host和transport.tcp.port即可
transport.host: localhost
transport.tcp.port: 9300
localhost可以是具體的IP地址
個人編寫的TransportClient和RestClient的github Demo:
https://github.com/qiushangwenyue/ElasticSearchDemo.git
參考資料:
https://www.elastic.co/guide/en/elasticsearch/client/index.html
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.4/java-rest-overview.html
https://blog.csdn.net/qq_33314107/article/details/80725913
Elasticsearch 6.4基本操作 - Java版