Elasticsearch整合:Springboot+Elasticsearch

Elasticsearch版本:7.9.3

ps:这里不使用springboot封装好类似与jpa的框架是因为在elasticsearch官方文档中并不推荐,并且在将来将会移除。

准备工作

1.设计好ES索引库,写好自己的Mode来接收elasticsearch返回的结果(也可以用String或JSON)

整合

1.引入依赖 (PS:因为Springboot自封装开箱的elasticsearch版本过低需要自己指定内部版本)

<!--指定springboot封装的es版本-->
<properties>
   <elasticsearch.version>7.9.3</elasticsearch.version>
</properties>

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

2.编写Springboot配置类(PS:目的从配置文件中获取配置ES信息)

/**
 * @description:
 * @create: 2021/4/11
 * @auther: twx 3094508274@qq.com
 **/
@Data
//说明配置文件前缀
@ConfigurationProperties(prefix = "es")
//配置类注解
@Configuration
@Slf4j
public class ElasticsearchConfig {
    //索引库
		private String index;
		//ES服务ip
    private String ip;
		//ES服务端口
    private String port;
		//ES请求 Http/Https
    private String schema;


}

3.编写elasticsearchClient(PS:封装ES的Client,因为其底层是长连接可以初始化后无需关闭一直使用,所以可以在项目中初始化后一直使用)

@Component
@Slf4j
public class ElasticClient {

		//注入配置文件读取到的信息
    @Resource
    ElasticsearchConfig config;
		//初始化 RestHighLevelClient
    private static RestHighLevelClient client = null;

		//声明bean
    @Bean
    public RestHighLevelClient getClient() {
        if (client != null) {
            return client;
        } else {
						//保证长连接唯一
            synchronized (ElasticClient.class) {
								//初始化client连接
                RestClientBuilder clientBuilder = RestClient.builder(new HttpHost(config.getIp(), Integer.parseInt(config.getPort()), config.getSchema()));
                client = new RestHighLevelClient(clientBuilder);
                log.info("创建ES连接成功");
                return client;
            }
        }
    }
}

4.封装Elasticsearch实体(PS:用于工具类的插入)

/**
 * @description: elastic实体类
 * @create: 2021/4/11
 * @auther: twx 3094508274@qq.com
 **/
@Data
public class ElasticEntity<T> {
    private String id;
    private T data;
}

5.封装Elasticsearch工具类(只做简单的封装,如分页返回,实体返回)

/**
 * @description: es工具类封装
 * @create: 2021/4/11
 * @auther: twx 3094508274@qq.com
 *
 * 入参解释
 * QueryBuilder 查询构造
 * SortBuilder 排序构造
 * elementType 转换实体
 **/
@Component
@Slf4j
public class EsUtil {

    private static ElasticsearchConfig config;

    private static ElasticClient elasticClient;

    @Autowired
    public void setConfig(ElasticsearchConfig config) {
        EsUtil.config = config;
    }

    @Autowired
    public void setClient(ElasticClient elasticClient) {
        EsUtil.elasticClient = elasticClient;
    }


    /** 默认索引库插入数据(单记录插入)
     * @param entity
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:20
     **/
    @SneakyThrows
    public static boolean insertOrUpdateOne(ElasticEntity entity) {
        return insertOrUpdateOne(entity,config.getIndex());
    }

    /** 自定义索引库插入数据(单条)
     * @param entity
     * @param index
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:20
     **/
    @SneakyThrows
    public static boolean insertOrUpdateOne(ElasticEntity entity,String index) {
        IndexRequest request = new IndexRequest(index);
        log.warn("Data: id={},entity={}", entity.getId(), entity.getData());
        if (StrUtil.isNotEmpty(entity.getId())) {
            request.id(entity.getId());
        }
        request.source(JSONObject.toJSONString(entity.getData(), SerializerFeature.WriteDateUseDateFormat), XContentType.JSON);
        if (StrUtil.isNotEmpty(entity.getId())) {
            request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
        }
        IndexResponse indexResponse = elasticClient.getClient().index(request, RequestOptions.DEFAULT);
        int status = indexResponse.status().getStatus();
        if ((status == RestStatus.CREATED.getStatus()) || (status == RestStatus.OK.getStatus())) {
            return true;
        }

        return false;
    }

    /** 默认索引库分页查询
     * @param pageNum
     * @param pageSize
     * @param queryBuilder
     * @param sortBuilderList
     * @param elementType
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:22
     **/
    @SneakyThrows
    public static <T> EsPage<T> queryPage(int pageNum, int pageSize, QueryBuilder queryBuilder, List<SortBuilder<?>> sortBuilderList, Class<T> elementType) {
        return queryPage(pageNum,pageSize,queryBuilder,sortBuilderList,elementType,config.getIndex());
    }

    /** 使用自定义索引库分页查询(可多个索引库查询)
     * @param pageNum
     * @param pageSize
     * @param queryBuilder
     * @param sortBuilderList
     * @param elementType
     * @param values
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:23
     **/
    @SneakyThrows
    public static <T> EsPage<T> queryPage(int pageNum, int pageSize, QueryBuilder queryBuilder, List<SortBuilder<?>> sortBuilderList,Class<T> elementType, String... values){
        if (pageNum <= 1) {
            pageNum = 0;
        } else {
            pageNum = pageNum - 1;
        }

        //构建Source字段
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder).from(pageNum * pageSize).size(pageSize);
        if (CollUtil.isNotEmpty(sortBuilderList)) {
            sortBuilderList.forEach(sortBuilder -> {
                searchSourceBuilder.sort(sortBuilder);
            });
        }
        //查询请求
        SearchRequest request = new SearchRequest(values);
        request.source(searchSourceBuilder);
        //查询响应
        SearchResponse searchResponse = elasticClient.getClient().search(request, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        List<String> list = new ArrayList<>();
        for (SearchHit hit : hits) {
            list.add(hit.getSourceAsString());
        }
        List<T> dataList = new ArrayList<>();
        list.forEach(s -> {
            T data = JSONObject.parseObject(s, elementType);
            dataList.add(data);
        });
        EsPage<T> esPage = new EsPage<>();
        esPage.setTotal(searchResponse.getHits().getTotalHits().value);
        esPage.setPage(pageNum);
        esPage.setData(dataList);
        return esPage;
    }


    /** 使用默认索引库查询 非分页查询
     * @param queryBuilder
     * @param sortBuilderList
     * @param elementType
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:24
     **/
    @SneakyThrows
    public static <T> List<T> queryList(QueryBuilder queryBuilder, List<SortBuilder<?>> sortBuilderList, Class<T> elementType,int size) {
        return queryList(queryBuilder,sortBuilderList,elementType,size,config.getIndex());
    }


    /** 自定义索引库查询 非分页查询(可多个索引库查询)
     * @param queryBuilder
     * @param sortBuilderList
     * @param elementType
     * @param size
     * @param values
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:26
     **/
    @SneakyThrows
    public static <T> List<T> queryList(QueryBuilder queryBuilder, List<SortBuilder<?>> sortBuilderList, Class<T> elementType,int size, String... values) {

        //构建Source字段
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder).size(size);
        if (CollUtil.isNotEmpty(sortBuilderList)) {
            sortBuilderList.forEach(sortBuilder -> {
                searchSourceBuilder.sort(sortBuilder);
            });
        }
        //查询请求
        SearchRequest request = new SearchRequest(values);
        request.source(searchSourceBuilder);
        //查询响应
        SearchResponse searchResponse = elasticClient.getClient().search(request, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        List<String> list = new ArrayList<>();
        for (SearchHit hit : hits) {
            list.add(hit.getSourceAsString());
        }
        List<T> dataList = new ArrayList<>();
        list.forEach(s -> {
            T data = JSONObject.parseObject(s, elementType);
            dataList.add(data);
        });
        return dataList;
    }


    /** 查询单个数据
     * @param queryBuilder
     * @param elementType
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:26
     **/
    @SneakyThrows
    public static <T> EsOne<T> selectOne(QueryBuilder queryBuilder, Class<T> elementType) {
        return selectOne(queryBuilder,elementType,config.getIndex());
    }

    /** 查询单个数据(可多个索引库)如有多条只返回第一个
     * @param queryBuilder
     * @param elementType
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:26
     **/
    @SneakyThrows
    public static <T> EsOne<T> selectOne(QueryBuilder queryBuilder, Class<T> elementType, String... values) {
        //构建Source字段
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder);
        //查询请求
        SearchRequest request = new SearchRequest(values);
        request.source(searchSourceBuilder);
        //查询响应
        SearchResponse searchResponse = elasticClient.getClient().search(request, RequestOptions.DEFAULT);
        SearchHit[] hit = searchResponse.getHits().getHits();
        EsOne<T> one = new EsOne<>();
        if (hit.length <= 0) {
            return null;
        }
        one.setId(hit[0].getId());
        T data = JSONObject.parseObject(hit[0].getSourceAsString(), elementType);
        one.setData(data);
        return one;
    }


    /** 默认索引库中删除
     * @param id
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:30
     **/
    @SneakyThrows
    public static void deleteById(String id) {
        deleteById(id,config.getIndex());
    }

    /** 自定义索引库中删除
     * @param id
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:30
     **/
    @SneakyThrows
    public static void deleteById(String id,String index) {
        DeleteRequest request = new DeleteRequest(index, id);
        DeleteResponse deleteResponse = elasticClient.getClient().delete(request, RequestOptions.DEFAULT);
        String result = deleteResponse.getResult().name();
        if (!DocWriteResponse.Result.DELETED.name().equals(result)) {
            throw new RuntimeException("删除失败,请联系管理员");
        }
    }

    /** 默认索引库统计数量
     * @param queryBuilder
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:30
     **/
    public static Long count(QueryBuilder queryBuilder) {
        return count(queryBuilder,config.getIndex());
    }

    /** 自定义索引库
     * @param queryBuilder
     * @param values
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:31
     **/
    @SneakyThrows
    public static Long count(QueryBuilder queryBuilder,String... values) {
        CountRequest countRequest = new CountRequest(values);
        countRequest.query(queryBuilder);
        CountResponse countResponse = elasticClient.getClient().count(countRequest, RequestOptions.DEFAULT);
        return countResponse.getCount();
    }

    /**
     * 查询范围构造器 gte 大于等于 lte 小于等于 gt 大于 lt 小于
     *
     * @param fieldKey 查询字段
     * @param start    大于值
     * @param end      小于值
     * @param e        是否开启等于条件   true开启
     * @return
     */
    public static RangeQueryBuilder rangeQueryBuilder(String fieldKey, String start, String end, boolean e) {
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(fieldKey);
        if (e) {
            if (StrUtil.isNotEmpty(start)) {
                rangeQueryBuilder.gte(start);
            }

            if (StrUtil.isNotEmpty(end)) {
                rangeQueryBuilder.lte(end);
            }
        } else {
            if (StrUtil.isNotEmpty(start)) {
                rangeQueryBuilder.gt(start);
            }

            if (StrUtil.isNotEmpty(end)) {
                rangeQueryBuilder.lt(end);
            }
        }
        return rangeQueryBuilder;
    }

    /** 带评分查询(尚未测试)
     * @param suggestionBuilder
     * @param num
     * @author: twx 3094508274@qq.com
     * @date: 2021/6/17 11:42
     **/
    @SneakyThrows
    public static List<String> suggestSelect(SuggestionBuilder suggestionBuilder, int num) {

        //查询构造
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        String name = RandomUtil.randomStringUpper(4);
        //suggest构造
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder.addSuggestion(name, suggestionBuilder);
        searchSourceBuilder.suggest(suggestBuilder);


        //查询请求
        SearchRequest request = new SearchRequest(config.getIndex());
        request.source(searchSourceBuilder);


        //查询响应
        SearchResponse response = elasticClient.getClient().search(request, RequestOptions.DEFAULT);
        //suggest实体
        Suggest suggest = response.getSuggest();
        Set<String> result = new HashSet<>();
        int maxSuggest = 0;
        //获取suggest,name任意string
        if (suggest != null) {
            Suggest.Suggestion data = suggest.getSuggestion(name);
            for (Object term : data.getEntries()) {
                if (term instanceof CompletionSuggestion.Entry) {
                    CompletionSuggestion.Entry item = (CompletionSuggestion.Entry) term;
                    if (!item.getOptions().isEmpty()) {
                        //若item的option不为空,循环遍历
                        for (CompletionSuggestion.Entry.Option option : item.getOptions()) {
                            String s = option.getText().toString();
                            //没重复则加入
                            if (!result.contains(s)) {
                                result.add(s);
                                ++maxSuggest;
                            }
                        }
                    }
                }
                if (maxSuggest >= num) {
                    break;
                }
            }
        }

        return new ArrayList<>(result);
    }
}

6.工具类所需要的VO类

//单个查询VO封装 ID属性是为了区分ES自生成Id 与业务ID不为同一个(也可以设置ESid为业务id)
/**
 * @author twx
 * @description:
 * @create: 2021/4/11
 **/
@Data
public class EsOne<T> implements Serializable {

    private static final long serialVersionUID = -3928293688231914175L;
    private String id;

    private T data;
}
/**
 * @author twx
 * @description: es分页返回实体
 * @create: 2021/4/11
 **/
@Data
public class EsPage<T> implements Serializable {

    private static final long serialVersionUID = 8426920253860658973L;
    private long total;

    private long page;

    private List<T> data;
}

7.调用示例

public class Test {

    public static void main(String[] args) {
        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title","111");
        EsOne<自己的实体类> one = EsUtil.selectOne(matchQueryBuilder,自己的实体类.class);
        one.getData();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值