【ES学习系列】RestHighLevelClient使用实例

 配置文件

(pom.xml):

    <!--jar包版本-->
    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.9.3</elasticsearch.version>
        <hutu.version>4.6.1</hutu.version>
        <springSwagger.version>2.6.1</springSwagger.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>${elasticsearch.version}</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>${elasticsearch.version}</version>
        </dependency>
        <!-- 第三方util -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutu.version}</version>
        </dependency>
        <!-- 接口文档生成 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${springSwagger.version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${springSwagger.version}</version>
        </dependency>
    </dependencies>

(application.yml):

server:
  port: 9000
spring:
  main:
    allow-bean-definition-overriding: true
  basePackage: com.karat.es
  resources:
    static-locations: classpath:/static, classpath:/templates
  jackson:
    #参数意义:
    #JsonInclude.Include.ALWAYS       默认
    #JsonInclude.Include.NON_DEFAULT   属性为默认值不序列化
    #JsonInclude.Include.NON_EMPTY     属性为 空(””) 或者为 NULL 都不序列化
    #JsonInclude.Include.NON_NULL      属性为NULL  不序列化
    default-property-inclusion: ALWAYS
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss
elasticsearch:
  hosts: 127.0.0.1 #集群地址,多个用,隔开
  port: 9200 # 使用的端口号
  schema: http #使用的协议
  connectTimeOut: 1000 #连接超时时间
  socketTimeOut: 30000 #连接超时时间
  connectionRequestTimeOut: 500 #获取连接的超时时间
  maxConnectNum: 100 #最大连接数
  maxConnectPerRoute: 100 #最大路由连接数
  preStr: es_test_
swagger2:
  open: true
  testToken: Get after landing
  basePackage: ${spring.basePackage}
  name:
  url:
  email:
  title: springboot利用swagger构建api文档
  description: springboot利用swagger构建api文档

配置类

(EsConfig.java):

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@ConfigurationProperties(prefix = "elasticsearch", ignoreInvalidFields = true)
@Getter
@Setter
@Component
public class EsConfig {

    private String hosts;
    private int port;
    private String schema;
    private int connectTimeOut;
    private int socketTimeOut;
    private int connectionRequestTimeOut;
    private int maxConnectNum;
    private int maxConnectPerRoute;
    private String preStr;
}

(EsConfiguration.java):

import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
import org.elasticsearch.client.RestClientBuilder.RequestConfigCallback;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

@Configuration
public class EsConfiguration {

    @Resource
    EsConfig config;

    @Bean
    public RestHighLevelClient client() {
        RestClientBuilder builder = RestClient.builder(new HttpHost(config.getHosts(),config.getPort(),config.getSchema()));
        // 异步httpclient连接延时配置
        builder.setRequestConfigCallback(new RequestConfigCallback() {
            @Override
            public Builder customizeRequestConfig(Builder requestConfigBuilder) {
                requestConfigBuilder.setConnectTimeout(config.getConnectTimeOut());
                requestConfigBuilder.setSocketTimeout(config.getSocketTimeOut());
                requestConfigBuilder.setConnectionRequestTimeout(config.getConnectionRequestTimeOut());
                return requestConfigBuilder;
            }
        });
        // 异步httpclient连接数配置
        builder.setHttpClientConfigCallback(new HttpClientConfigCallback() {
            @Override
            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                httpClientBuilder.setMaxConnTotal(config.getMaxConnectNum());
                httpClientBuilder.setMaxConnPerRoute(config.getMaxConnectPerRoute());
                return httpClientBuilder;
            }
        });
        RestHighLevelClient client = new RestHighLevelClient(builder);
        return client;
    }

}

存储对象

(EsBean.java):

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.util.Date;

@Data
public class EsBean {
    private String id;
    private String name;
    private int age;
    private String phone;
    @JsonFormat(
            pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8"
    )
    protected Date createTime;
}

(PageEsBean.java):

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;

import java.util.Date;

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class PageEsBean extends EsBean{

    //每页大小
    private int pageSize=1;
    //当前页
    private int pageNum=3;
    //结束范围时间段
    @JsonFormat(
            pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8"
    )
    protected Date endTime;
    //开始范围时间段
    @JsonFormat(
            pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8"
    )
    protected Date beginTime;

}

Es服务

(RestHighLevelClientService.java):

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.karat.es.bean.EsBean;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;

import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class RestHighLevelClientService {

    @Resource
    private RestHighLevelClient client;
    @Value("${elasticsearch.preStr}")
    private String preStr;

    /**
     * 获取索引
     * @param beanClass
     * @return
     */
    public String getIndex(Class beanClass) {
        return preStr + StrUtil.toUnderlineCase(beanClass.getSimpleName()).toLowerCase();
    }


    /**
     * 创建索引
     * @param index 索引名称
     * @throws IOException
     */
    public void createIndex(String index) throws IOException {
        CreateIndexRequest request = new CreateIndexRequest(index);
        CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
        log.info("创建索引: {}", JSONUtil.toJsonStr(createIndexResponse));
    }

    /**
     * 判断索引是否存在
     * @param index 索引名称
     * @return
     * @throws IOException
     */
    public boolean existsIndex(String index) throws IOException {
        GetIndexRequest request = new GetIndexRequest();
        request.indices(index);
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        log.info("判断索引是否存在: {}",exists);
        return exists;
    }

    /**
     * 增加记录
     * @param esBean 数据
     * @throws IOException
     */
    public boolean insert(EsBean esBean) throws IOException {
        String index = getIndex(esBean.getClass());
        IndexRequest indexRequest = new IndexRequest(index);// 创建索引请求对象
        indexRequest.id(esBean.getId());
        indexRequest.source(JSONUtil.toJsonStr(esBean), XContentType.JSON);// 设置文档内容
        IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);// 执行增加文档
        log.info("增加记录:{},状态码:{}",JSONUtil.toJsonStr(response),response.status().getStatus());
        if (!exists(index, esBean.getId())) {
            log.error("文档不存在: {}, 行号:{}", esBean.getId(), new Throwable().getStackTrace()[0].getLineNumber());
            return false;
        }else{
            return true;
        }
    }

    /**
     * 判断记录是都存在
     * @param index 索引名称
     * @param id 数据ID主键
     * @return
     * @throws IOException
     */
    public boolean exists(String index, String id) throws IOException {
        GetRequest getRequest = new GetRequest(index, id);
        boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
        log.info("判断记录是都存在: {}",exists);
        return exists;
    }


    /**
     * 获取记录信息
     * @param id 记录主键ID
     * @param beanClass  获取数据Bean对象
     * @throws IOException
     */
    public <T> T get(String id,Class<T> beanClass) throws Exception {
        T t = beanClass.newInstance();
        //查看索引
        String index = getIndex(beanClass);
        if (!exists(index, id)) {
            log.error("文档不存在: {}, 行号:{}", id, new Throwable().getStackTrace()[0].getLineNumber());
            return null;
        }
        //单条查询
        GetRequest getRequest = new GetRequest(index, id);
        GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
        log.info("获取记录信息: 索引:{},Id:{}",response.getIndex(),response.getId());
        // 将 JSON 转换成对象
        if (response.isExists()) {
            t = JSONUtil.toBean(response.getSourceAsString(), beanClass);
        }
        return t;
    }

    /**
     * 更新记录信息
     * @param esBean 数据
     * @throws IOException
     */
    public boolean update(EsBean esBean){
        try {
            String index = getIndex(esBean.getClass());
            if (!existsIndex(index)) {
                log.error("索引不存在: {}, 行号:{}", index, new Throwable().getStackTrace()[0].getLineNumber());
                return false;
            }
            if (!exists(index, esBean.getId())) {
                log.error("文档不存在: {}, 行号:{}", esBean.getId(), new Throwable().getStackTrace()[0].getLineNumber());
                return false;
            }
            UpdateRequest request = new UpdateRequest(index, esBean.getId());// 创建索引请求对象
            request.doc(JSONUtil.toJsonStr(esBean), XContentType.JSON);// 设置更新文档内容
            UpdateResponse response = client.update(request, RequestOptions.DEFAULT);// 执行更新文档
            log.info("更新记录信息: {},状态码:{}",JSONUtil.toJsonStr(response),response.status());
            return RestStatus.OK.equals(response.status());
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除记录
     * @param beanClass 删除对象
     * @param id 索引数据ID
     * @throws IOException
     */
    public boolean delete(String id,Class beanClass) throws IOException {
        String index = getIndex(beanClass);
        if (!existsIndex(index)) {
            log.error("索引不存在: {}, 行号:{}", index, new Throwable().getStackTrace()[0].getLineNumber());
            return false;
        }
        if (!exists(index, id)) {
            log.error("文档不存在: {}, 行号:{}", id, new Throwable().getStackTrace()[0].getLineNumber());
            return false;
        }
        DeleteRequest deleteRequest = new DeleteRequest(index, id);
        DeleteResponse response = client.delete(deleteRequest, RequestOptions.DEFAULT);
        log.info("删除记录: {}",JSONUtil.toJsonStr(response));
        return RestStatus.OK.equals(response.status());
    }

    /**
     * 搜索
     * 自定义条件查询,多条文档
     * @param searchSourceBuilder 构建查询条件(注意:termQuery 支持多种格式查询,如 boolean、int、double、string 等,这里使用的是 string 的查询)
     * @param beanClass
     * @throws IOException
     */
    public <T> List<T> search(SearchSourceBuilder searchSourceBuilder, Class<T> beanClass) {
        try {
            String index = getIndex(beanClass);
            if (!existsIndex(index)) {
                log.error("索引不存在: {}, 行号:{}", index, new Throwable().getStackTrace()[0].getLineNumber());
                return new ArrayList<>();
            }
            SearchRequest searchRequest = new SearchRequest(index);
            searchRequest.source(searchSourceBuilder);
            SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
            log.info("搜索:{}-状态:{}-总条数:{}",JSONUtil.toJsonStr(response),response.status(),response.getHits().getTotalHits().value);
            if (RestStatus.OK.equals(response.status()) && response.getHits().getHits().length > 0) {
                SearchHits hits = response.getHits();
                List<T> list = new ArrayList<>();
                for (SearchHit hit : hits) {
                    // 将 JSON 转换成对象
                    T t = JSONUtil.toBean(hit.getSourceAsString(), beanClass);
                    // 输出查询信息
                    list.add(t);
                }
                return list;
            }
            return null;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

}
import com.karat.es.bean.EsBean;
import com.karat.es.bean.PageEsBean;
import com.karat.es.service.RestHighLevelClientService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping(value = "es")
@Api(value = "EsController", description = "es测试", produces = MediaType.APPLICATION_JSON_VALUE)
public class RestHighLevelClientController {

    @Resource
    RestHighLevelClientService restHighLevelClientService;

    @RequestMapping(value = "add", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "增", httpMethod = "POST", notes = "add")
    public boolean add(@RequestBody EsBean esBean)throws Exception{
        esBean.setId(UUID.randomUUID().toString());
        esBean.setCreateTime(new Date());
        return restHighLevelClientService.insert(esBean);
    }

    @RequestMapping(value = "del", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "删", httpMethod = "GET", notes = "del")
    public boolean del(@RequestParam("id")String id) throws Exception{
        return restHighLevelClientService.delete(id,EsBean.class);
    }

    @RequestMapping(value = "update", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "改", httpMethod = "POST", notes = "update")
    public boolean update(@RequestBody EsBean esBean){
        esBean.setCreateTime(new Date());
        return restHighLevelClientService.update(esBean);
    }

    @RequestMapping(value = "get", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "查", httpMethod = "GET", notes = "get")
    public EsBean test(@RequestParam("id")String id) throws Exception{
        return restHighLevelClientService.get(id,EsBean.class);
    }

    @RequestMapping(value = "search", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "多条件查询", httpMethod = "POST", notes = "search")
    public List search(@RequestBody PageEsBean pageEsBean){
        // 构建查询条件
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //多条件设置
        if(!pageEsBean.getName().equals("")){
            boolBuilder.must(QueryBuilders.matchPhraseQuery("name" ,pageEsBean.getName()));
        }
        if(pageEsBean.getAge()!=0){
            boolBuilder.must(QueryBuilders.matchPhraseQuery("age" ,pageEsBean.getAge()));
        }
        //时间段查询
        if(pageEsBean.getBeginTime()!=null&&pageEsBean.getEndTime()!=null){
            boolBuilder.must(QueryBuilders.rangeQuery("createTime").gte(pageEsBean.getBeginTime().getTime()).lte(pageEsBean.getEndTime().getTime()));
        }
        //分页从0开始 设置从第几条开始查询
        searchSourceBuilder.from((pageEsBean.getPageNum()-1)*pageEsBean.getPageSize()).size(pageEsBean.getPageSize());
        // 倒序
        searchSourceBuilder.sort("createTime", SortOrder.DESC);
        //trackTotalHits(true) 设置查询索引中数据总条数
        searchSourceBuilder.trackTotalHits(true);
        searchSourceBuilder.query(boolBuilder);
        return restHighLevelClientService.search(searchSourceBuilder,new EsBean().getClass());
    }

}

Demo目录结构

 

posted @ 2022-01-14 15:22  21karat  阅读(1839)  评论(1编辑  收藏  举报