• 中间件: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·点这里 ☆☆☆☆☆
  • 相关阅读:
    单表查询
    阻塞非阻塞同步异步&异步回调
    基于协程的TCP并发编程
    协程
    死锁与递归锁
    线程池和进程池
    GIL全局解释器锁
    数据库——多表关系
    常用数据类型与约束
    Python基础(目录)
  • 原文地址:https://www.cnblogs.com/jiehanshi/p/14323491.html
Copyright © 2020-2023  润新知