中間件:ElasticSearch組件RestHighLevelClient用法詳解


摘自知了一笑的博客:https://www.cnblogs.com/cicada-smile/

本文源碼:GitHub·點這里 || GitEE·點這里

一、基礎API簡介

1、RestHighLevelClient

RestHighLevelClient的API作為ElasticSearch備受推薦的客戶端組件,其封裝系統操作ES的方法,包括索引結構管理,數據增刪改查管理,常用查詢方法,並且可以結合原生ES查詢原生語法,功能十分強大。

在使用RestHighLevelClient的語法時,通常涉及上面幾個方面,在掌握基礎用法之上可以根據業務特點進行一些自定義封裝,這樣可以更優雅的解決業務需求。

2、核心依賴

使用RestHighLevelClient需要依賴rest-high-level-client包,和ES相關基礎依賴。

<dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-client</artifactId> </dependency> <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency> 

二、索引管理

這里不做過多描述,注意一點:因為ES的數據結構特點,所以不需要索引更新方法,新的字段在更新數據時直接寫入即可,不需要提前更新索引結構。

@Service public class EsIndexOperation { @Resource private RestHighLevelClient client ; private final RequestOptions options = RequestOptions.DEFAULT; /** * 判斷索引是否存在 */ public boolean checkIndex (String index) { try { return client.indices().exists(new GetIndexRequest(index), options); } catch (IOException e) { e.printStackTrace(); } return Boolean.FALSE ; } /** * 創建索引 */ public boolean createIndex (String indexName ,Map<String, Object> columnMap){ try { if(!checkIndex(indexName)){ CreateIndexRequest request = new CreateIndexRequest(indexName); if (columnMap != null && columnMap.size()>0) { Map<String, Object> source = new HashMap<>(); source.put("properties", columnMap); request.mapping(source); } this.client.indices().create(request, options); return Boolean.TRUE ; } } catch (IOException e) { e.printStackTrace(); } return Boolean.FALSE; } /** * 刪除索引 */ public boolean deleteIndex(String indexName) { try { if(checkIndex(indexName)){ DeleteIndexRequest request = new DeleteIndexRequest(indexName); AcknowledgedResponse response = client.indices().delete(request, options); return response.isAcknowledged(); } } catch (Exception e) { e.printStackTrace(); } return Boolean.FALSE; } } 

三、數據管理

這里在更新數據時,可以直接修改索引結構,在dataMap中放進新的字段即可。

@Service public class EsDataOperation { @Resource private RestHighLevelClient client ; private final RequestOptions options = RequestOptions.DEFAULT; /** * 寫入數據 */ public boolean insert (String indexName, Map<String,Object> dataMap){ try { BulkRequest request = new BulkRequest(); request.add(new IndexRequest(indexName,"doc").id(dataMap.remove("id").toString()) .opType("create").source(dataMap,XContentType.JSON)); this.client.bulk(request, options); return Boolean.TRUE ; } catch (Exception e){ e.printStackTrace(); } return Boolean.FALSE; } /** * 批量寫入數據 */ public boolean batchInsert (String indexName, List<Map<String,Object>> userIndexList){ try { BulkRequest request = new BulkRequest(); for (Map<String,Object> dataMap:userIndexList){ request.add(new IndexRequest(indexName,"doc").id(dataMap.remove("id").toString()) .opType("create").source(dataMap,XContentType.JSON)); } this.client.bulk(request, options); return Boolean.TRUE ; } catch (Exception e){ e.printStackTrace(); } return Boolean.FALSE; } /** * 更新數據,可以直接修改索引結構 */ public boolean update (String indexName, Map<String,Object> dataMap){ try { UpdateRequest updateRequest = new UpdateRequest(indexName,"doc", dataMap.remove("id").toString()); updateRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE); updateRequest.doc(dataMap) ; this.client.update(updateRequest, options); return Boolean.TRUE ; } catch (Exception e){ e.printStackTrace(); } return Boolean.FALSE; } /** * 刪除數據 */ public boolean delete (String indexName, String id){ try { DeleteRequest deleteRequest = new DeleteRequest(indexName,"doc", id); this.client.delete(deleteRequest, options); return Boolean.TRUE ; } catch (Exception e){ e.printStackTrace(); } return Boolean.FALSE; } } 

四、查詢操作

注意:查詢總數的CountRequest語法,SearchRequest查詢結果中數據轉換語法,分頁查詢中需要指定偏移位置和分頁大小。

@Service
public class EsQueryOperation { @Resource private RestHighLevelClient client ; private final RequestOptions options = RequestOptions.DEFAULT; /** * 查詢總數 */ public Long count (String indexName){ // 指定創建時間 BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); queryBuilder.must(QueryBuilders.termQuery("createTime", 1611378102795L)); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.query(queryBuilder); CountRequest countRequest = new CountRequest(indexName); countRequest.source(sourceBuilder); try { CountResponse countResponse = client.count(countRequest, options); return countResponse.getCount(); } catch (Exception e) { e.printStackTrace(); } return 0L; } /** * 查詢集合 */ public List<Map<String,Object>> list (String indexName) { // 查詢條件,指定時間並過濾指定字段值 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); queryBuilder.must(QueryBuilders.termQuery("createTime", 1611378102795L)); queryBuilder.mustNot(QueryBuilders.termQuery("name","北京-李四")); sourceBuilder.query(queryBuilder); SearchRequest searchRequest = new SearchRequest(indexName); searchRequest.source(sourceBuilder); try { SearchResponse searchResp = client.search(searchRequest, options); List<Map<String,Object>> data = new ArrayList<>() ; SearchHit[] searchHitArr = searchResp.getHits().getHits(); for (SearchHit searchHit:searchHitArr){ Map<String,Object> temp = searchHit.getSourceAsMap(); temp.put("id",searchHit.getId()) ; data.add(temp); } return data; } catch (Exception e) { e.printStackTrace(); } return null ; } /** * 分頁查詢 */ public List<Map<String,Object>> page (String indexName,Integer offset,Integer size) { // 查詢條件,指定時間並過濾指定字段值 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.from(offset); sourceBuilder.size(size); sourceBuilder.sort("createTime", SortOrder.DESC); SearchRequest searchRequest = new SearchRequest(indexName); searchRequest.source(sourceBuilder); try { SearchResponse searchResp = client.search(searchRequest, options); List<Map<String,Object>> data = new ArrayList<>() ; SearchHit[] searchHitArr = searchResp.getHits().getHits(); for (SearchHit searchHit:searchHitArr){ Map<String,Object> temp = searchHit.getSourceAsMap(); temp.put("id",searchHit.getId()) ; data.add(temp); } return data; } catch (Exception e) { e.printStackTrace(); } return null ; } } 

五、排序方式

排序除了常規的指定字段升序降序規則之外,還可以基於原生的腳本語法,基於自定義規則排序讓一些特定的數據沉底或者置頂。

@Service public class EsSortOperation { @Resource private RestHighLevelClient client ; private final RequestOptions options = RequestOptions.DEFAULT; /** * 排序規則 */ public List<Map<String,Object>> sort (String indexName) { // 先升序時間,在倒序年齡 SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.sort("createTime", SortOrder.ASC); sourceBuilder.sort("age",SortOrder.DESC) ; SearchRequest searchRequest = new SearchRequest(indexName); searchRequest.source(sourceBuilder); try { SearchResponse searchResp = client.search(searchRequest, options); List<Map<String,Object>> data = new ArrayList<>() ; SearchHit[] searchHitArr = searchResp.getHits().getHits(); for (SearchHit searchHit:searchHitArr){ Map<String,Object> temp = searchHit.getSourceAsMap(); temp.put("id",searchHit.getId()) ; data.add(temp); } return data; } catch (Exception e) { e.printStackTrace(); } return null ; } /** * 自定義排序規則 */ public List<Map<String,Object>> defSort (String indexName) { // 指定置換順序的規則 // [age 12-->60]\[age 19-->10]\[age 13-->30]\[age 18-->40],age其他值忽略為1 Script script = new Script("def _ageSort = doc['age'].value == 12?60:" + "(doc['age'].value == 19?10:" + "(doc['age'].value == 13?30:" + "(doc['age'].value == 18?40:1)));" + "_ageSort;"); ScriptSortBuilder sortBuilder = SortBuilders.scriptSort(script,ScriptSortBuilder.ScriptSortType.NUMBER); sortBuilder.order(SortOrder.ASC); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.sort(sortBuilder); SearchRequest searchRequest = new SearchRequest(indexName); searchRequest.source(sourceBuilder); try { SearchResponse searchResp = client.search(searchRequest, options); List<Map<String,Object>> data = new ArrayList<>() ; SearchHit[] searchHitArr = searchResp.getHits().getHits(); for (SearchHit searchHit:searchHitArr){ Map<String,Object> temp = searchHit.getSourceAsMap(); temp.put("id",searchHit.getId()) ; data.add(temp); } return data; } catch (Exception e) { e.printStackTrace(); } return null ; } } 

六、源代碼地址

GitHub·地址 https://github.com/cicadasmile/data-manage-parent GitEE·地址 https://gitee.com/cicadasmile/data-manage-parent 

推薦閱讀:編程體系整理

序號 項目名稱 GitHub地址 GitEE地址 推薦指數
01 Java描述設計模式,算法,數據結構 GitHub·點這里 GitEE·點這里 ☆☆☆☆☆
02 Java基礎、並發、面向對象、Web開發 GitHub·點這里 GitEE·點這里 ☆☆☆☆
03 SpringCloud微服務基礎組件案例詳解 GitHub·點這里 GitEE·點這里 ☆☆☆
04 SpringCloud微服務架構實戰綜合案例 GitHub·點這里 GitEE·點這里 ☆☆☆☆☆
05 SpringBoot框架基礎應用入門到進階 GitHub·點這里 GitEE·點這里 ☆☆☆☆
06 SpringBoot框架整合開發常用中間件 GitHub·點這里 GitEE·點這里 ☆☆☆☆☆
07 數據管理、分布式、架構設計基礎案例 GitHub·點這里 GitEE·點這里 ☆☆☆☆☆
08 大數據系列、存儲、組件、計算等框架 GitHub·點這里 GitEE·點這里 ☆☆☆☆☆


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM