ElasticSearch7入门(五)SpringBoot2.3.0集成ElasticSearch7.5.2-HighLevelClient

简介: ElasticSearch7入门(五)SpringBoot2.3.0集成ElasticSearch7.5.2-HighLevelClient

背景


今天来实现SpringBoot集成ElasticSearchElasticSearch官方提供了两种Java REST Client。推荐使用HighLevelClient的方式,HighLevelClient本身是基于Low Level REST Client封装而来。


The Java REST Client comes in 2 flavors:
Java Low Level REST Client: the official low-level client for Elasticsearch. It allows to communicate with an Elasticsearch cluster through http. Leaves requests marshalling and responses un-marshalling to users. It is compatible with all Elasticsearch versions.
Java High Level REST Client: the official high-level client for Elasticsearch. Based on the low-level client, it exposes API specific methods and takes care of requests marshalling and responses un-marshalling.


核心依赖


<!--ES-->
    <!--The High Level Java REST Client depends on the following artifacts and their transitive dependencies:
      org.elasticsearch.client:elasticsearch-rest-client
      org.elasticsearch:elasticsearch
    -->
    <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-high-level-client</artifactId>
      <version>7.5.2</version>
    </dependency>
    <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-client</artifactId>
      <version>7.5.2</version>
    </dependency>
    <dependency>
      <groupId>org.elasticsearch</groupId>
      <artifactId>elasticsearch</artifactId>
      <version>7.5.2</version>
    </dependency>


核心方法


package com.heartsuit.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
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.support.master.AcknowledgedResponse;
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.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * @Author Heartsuit
 * @Date 2020-06-04
 */
@Slf4j
@Component
public class ElasticSearchServiceImpl implements ElasticSearchService {
    private final RestHighLevelClient client;
    public ElasticSearchServiceImpl(RestHighLevelClient client) {
        this.client = client;
    }
    /**
     * 创建索引
     *
     * @param index 必须小写,格式参考文档,否则报错:Elasticsearch exception [type=invalid_index_name_exception, reason=Invalid index name [OK], must be lowercase]
     * @return 是否创建成功
     */
    @Override
    public boolean createIndex(String index) {
        CreateIndexResponse response;
        try {
            if (!this.existsIndex(index)) {
                response = client.indices().create(new CreateIndexRequest(index), RequestOptions.DEFAULT);
            } else {
                return true;//索引已存在
            }
        } catch (Exception e) {
            log.error("ElasticSearch 创建索引异常:{}", e.getMessage());
            return false;
        }
        return response.isAcknowledged();
    }
    /**
     * 判断索引是否存在
     *
     * @param index
     * @return
     */
    private boolean existsIndex(String index) throws IOException {
        return client.indices().exists(new GetIndexRequest(index), RequestOptions.DEFAULT);
    }
    /**
     * 删除索引
     *
     * @param index 必须小写,格式参考文档,否则:找不到大写索引名
     * @return 是否删除成功
     */
    @Override
    public boolean deleteIndex(String index) {
        AcknowledgedResponse response = null;
        try {
            if (this.existsIndex(index)) {
                response = client.indices().delete(new DeleteIndexRequest(index), RequestOptions.DEFAULT);
            } else {
                return true;//索引不存在
            }
        } catch (Exception e) {
            log.error("ElasticSearch 删除索引异常:{}", e.getMessage());
            return false;
        }
        return response.isAcknowledged();
    }
    /**
     * 创建文档
     * id相同则更新、不同则创建,数据格式(字段)不同则空,字段为追加模式
     *
     * @param index    索引
     * @param data     数据
     * @param dataType 格式类型    例:XContentType.JSON
     * @param id       唯一标识   put /index/1
     * @return
     */
    @Override
    public int insertDocument(String index, Object data, XContentType dataType, String id) {
        IndexRequest request = new IndexRequest(index);
        request.id(id);
        String dataString = JSONObject.toJSONString(data);
        request.source(dataString, dataType);
        IndexResponse response = null;
        try {
            response = client.index(request, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("ElasticSearch 创建文档异常:{}", e.getMessage());
        }
        return response != null ? response.status().getStatus() : 400;
    }
    /**
     * 获取文档
     *
     * @param index
     * @param id
     * @param mappingClass
     * @param <T>
     * @return
     */
    @Override
    public <T> T getDocument(String index, String id, Class<T> mappingClass) {
        GetResponse getResponse = null;
        try {
            if (this.existsIndex(index)) {
                GetRequest getRequest = new GetRequest(index, id);
                getResponse = client.get(getRequest, RequestOptions.DEFAULT);
                String sourceAsString = getResponse.getSourceAsString();
                if (sourceAsString == null || sourceAsString.isEmpty()) {
                    return null;
                }
                /**Jackson日期时间序列化问题:
                 * Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default constructor, exist): no String-argument constructor/factory method to deserialize from String value ('2020-06-04 15:07:54')
                 */
//                ObjectMapper objectMapper = new ObjectMapper();
//                objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
//                objectMapper.registerModule(new JavaTimeModule());
//                T result = objectMapper.readValue(sourceAsString, mappingClass);
                T result = JSON.parseObject(sourceAsString, mappingClass);
                return result;
            }
        } catch (Exception e) {
            log.error("ElasticSearch 获取文档异常:{}", e.getMessage());
        }
        return null;
    }
    /**
     * 更新文档信息
     *
     * @param index
     * @param data
     * @param dataType
     * @param id
     * @return
     */
    @Override
    public int updateDocument(String index, Object data, XContentType dataType, String id) {
        UpdateResponse updateResponse = null;
        try {
            if (this.existsIndex(index)) {
                UpdateRequest updateRequest = new UpdateRequest(index, id);
                String dataString = JSONObject.toJSONString(data);
                updateRequest.doc(dataString, dataType);
                updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
            }
        } catch (Exception e) {
            log.error("ElasticSearch 更新文档异常:{}", e.getMessage());
        }
        return updateResponse != null ? updateResponse.status().getStatus() : 400;
    }
    /**
     * 删除文档
     *
     * @param index
     * @param id
     * @return
     */
    @Override
    public int deleteDocument(String index, String id) {
        DeleteResponse deleteResponse = null;
        try {
            if (this.existsIndex(index)) {
                DeleteRequest deleteRequest = new DeleteRequest(index, id);
                deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
            }
        } catch (Exception e) {
            log.error("ElasticSearch 删除文档异常:{}", e.getMessage());
        }
        return deleteResponse != null ? deleteResponse.status().getStatus() : 400;
    }
    /**
     * 批量操作文档信息
     * 备注:暂局限入参list,可扩展其他<?>
     *
     * @param index
     * @param list     标识相同则覆盖,否则新增
     * @param dataType
     * @return
     */
    @Override
    public boolean batchInsertDocument(String index, List<?> list, XContentType dataType) {
        BulkRequest bulkRequest = new BulkRequest();
        for (Object obj : list) {
            // 自动生成id
            bulkRequest.add(new IndexRequest(index).source(JSON.toJSONString(obj), dataType));
        }
        BulkResponse bulk = null;
        try {
            bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("ElasticSearch批量操作文档信息异常:{}", e.getMessage());
        }
        return bulk != null && !bulk.hasFailures();
    }
    /**
     * 查询数据
     * 备注:可拓展深入精准查询、范围查询、模糊查询、匹配所有等
     *
     * @param index
     * @return
     */
    @Override
    public List<Map<String, Object>> searchDocument(String index) {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        MatchAllQueryBuilder termQueryBuilder = QueryBuilders.matchAllQuery();
        sourceBuilder.query(termQueryBuilder);
        // sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchRequest.source(sourceBuilder);
        SearchResponse search;
        try {
            search = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (Exception e) {
            log.error("ElasticSearch 查询数据异常:{}", e.getMessage());
            return null;
        }
        SearchHit[] hits = search.getHits().getHits();
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (SearchHit hit : hits) {
            mapList.add(hit.getSourceAsMap());
        }
        return mapList;
    }
    private void close(RestHighLevelClient client) {
        try {
            client.close();
        } catch (IOException e) {
            log.error("ElasticSearch 关闭异常:{}", e.getMessage());
        }
    }
}

Note: 使用FastJson替换了SpringBoot的默认Json解析器Jackson,


相关实践学习
以电商场景为例搭建AI语义搜索应用
本实验旨在通过阿里云Elasticsearch结合阿里云搜索开发工作台AI模型服务,构建一个高效、精准的语义搜索系统,模拟电商场景,深入理解AI搜索技术原理并掌握其实现过程。
ElasticSearch 最新快速入门教程
本课程由千锋教育提供。全文搜索的需求非常大。而开源的解决办法Elasricsearch(Elastic)就是一个非常好的工具。目前是全文搜索引擎的首选。本系列教程由浅入深讲解了在CentOS7系统下如何搭建ElasticSearch,如何使用Kibana实现各种方式的搜索并详细分析了搜索的原理,最后讲解了在Java应用中如何集成ElasticSearch并实现搜索。 &nbsp;
目录
相关文章
存储 JSON Java
855 0
|
10月前
|
JSON 分布式计算 大数据
springboot项目集成大数据第三方dolphinscheduler调度器
springboot项目集成大数据第三方dolphinscheduler调度器
632 3
|
分布式计算 大数据 Java
springboot项目集成大数据第三方dolphinscheduler调度器 执行/停止任务
springboot项目集成大数据第三方dolphinscheduler调度器 执行/停止任务
261 0
|
10月前
|
缓存 JSON 前端开发
第07课:Spring Boot集成Thymeleaf模板引擎
第07课:Spring Boot集成Thymeleaf模板引擎
846 0
第07课:Spring Boot集成Thymeleaf模板引擎
|
10月前
|
存储 人工智能 Java
Springboot集成AI Springboot3 集成阿里云百炼大模型CosyVoice2 实现Ai克隆语音(未持久化存储)
本项目基于Spring Boot 3.5.3与Java 17,集成阿里云百炼大模型CosyVoice2实现音色克隆与语音合成。内容涵盖项目搭建、音色创建、音频合成、音色管理等功能,适用于希望快速掌握Spring Boot集成语音AI技术的开发者。需提前注册阿里云并获取API Key。
|
10月前
|
Java 关系型数据库 MySQL
springboot项目集成dolphinscheduler调度器 实现datax数据同步任务
springboot项目集成dolphinscheduler调度器 实现datax数据同步任务
941 2
|
10月前
|
分布式计算 Java 大数据
springboot项目集成dolphinscheduler调度器 可拖拽spark任务管理
springboot项目集成dolphinscheduler调度器 可拖拽spark任务管理
511 2
|
10月前
|
缓存 监控 安全
电商API集成入门:从零开始搭建高效接口
在数字化电商时代,API集成成为企业提升效率、实现系统互联的关键。本文从零开始,逐步讲解如何搭建高效、可靠的电商API接口,适合初学者学习。内容涵盖API基础、认证安全、请求处理、性能优化等核心步骤,并提供Python代码示例与数学公式辅助理解。通过实践,读者可掌握构建优质电商API的技巧,提升用户体验与系统性能。
393 0
|
分布式计算 Java 大数据
springboot项目集成dolphinscheduler调度器 项目管理
springboot项目集成dolphinscheduler调度器 项目管理
286 0