springboot集成elasticsearch7.6版本,以及在微服务中的使用

springboot集成elasticsearch7.6版本,以及在微服务中的使用_第1张图片

ES概述

Elaticsearch简称为es, es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别(大数据时代)的数据。es也使用 Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。 据国际权威的数据库产品评测机构DB Engines的统计,在2016年1月,ElasticSearch已超过Solr等,成 为排名第一的搜索引擎类应用。

RestAPI

ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。官方文档地址:https://www.elastic.co/guide/en/elasticsearch/client/index.html

其中的Java Rest Client又包括两种:

  • Java Low Level Rest Client
  • Java High Level Rest Client

springboot集成elasticsearch7.6版本,以及在微服务中的使用_第2张图片

版本关系

下表显示了Spring数据发布系列使用的Elasticsearch版本和其中包含的Spring数据Elasticsearch版本,以及涉及该特定Spring数据发布系列的Spring引导版本
springboot集成elasticsearch7.6版本,以及在微服务中的使用_第3张图片

集成

本文记录了Spring Boot与Elasticsearch的整合方式,Spring boot的版本为2.6.4,Elasticsearch的版本为7.6.0。

注意:因为SpringBoot有默认的ES版本,所以我们需要覆盖默认的ES版本:

 <!--引入es的RestHighLevelClient依赖:-->
 <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-high-level-client</artifactId>
      <version>7.6.0</version>
  </dependency>

在SpringBoot中无需如此,可以直接导入

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

具体pom配置文件如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
     <groupId>com.sh</groupId>
     <version>3.4.0</version>
     <artifactId>sh-common-elasticsearch</artifactId>
    <name>hcode-es-api-1</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <!--自定义依赖版本-->
        <elasticsearch.version>7.6.0</elasticsearch.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

yml配置文件

elasticsearch:
cluster-nodes: node1`:9200,node2:9200,node3:9200
cluster-name: my-es

编写ES相关配置进行映射

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Data
@Configuration
@Component
@ConfigurationProperties("elasticsearch")
public class ESProperties {

    /**
     * 集群名称
     */
    private String clusterName;

    /**
     * 集群地址
     */
    private String clusterNodes;
}

然后编写配置文件,注入到Spring容器中

import lombok.RequiredArgsConstructor;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Configuration
public class ElasticsearchConfig {

    @Autowired
    private ESProperties esProperties;

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        // 初始化ES客户端的构造器
        RestClientBuilder builder = RestClient.builder(httpHostHandlerDev());
        return new RestHighLevelClient(builder);
    }


    private HttpHost[] httpHostHandlerDev() {
        String[] hosts = esProperties.getClusterNodes().split(",");
        HttpHost[] httpHosts = new HttpHost[hosts.length];
        for (int i = 0; i < hosts.length; i++) {
            httpHosts[i] = HttpHost.create(hosts[i]);
        }
        System.out.println();
        return httpHosts;
    }
}

SpringBoot中使用ES

注入RestHighLevelClient

    @Autowired
    private RestHighLevelClient esClient;

编写es util

import com.alibaba.fastjson.JSON;
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.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 *
 * @author: lenovo
 * @createTime: 2022/3/30
 * @Time: 9:44
 * Description: No Description
 */
@Component
public class EsUtils {

    @Autowired
    private RestHighLevelClient esClient;

    /**
     * 创建索引库
     * @param indexName
     * @return
     * @throws IOException
     */
    public boolean createIndex(String indexName) throws IOException {
        CreateIndexRequest request = new CreateIndexRequest(indexName);
        CreateIndexResponse response = esClient.indices().create(request, RequestOptions.DEFAULT);
        return response.isAcknowledged();
    }

    /**
     * 查看索引是否存在
     * @param indexName
     * @return
     * @throws IOException
     */
    public boolean existIndex(String indexName) throws IOException {
        GetIndexRequest request = new GetIndexRequest(indexName);
        return esClient.indices().exists(request, RequestOptions.DEFAULT);
    }

    /**
     * 删除索引库
     * @param indexName
     * @throws IOException
     */
    public boolean deleteHotelIndex(String indexName) throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest(indexName);
        boolean delFlag = false;
        // 1.创建Request对象
        GetIndexRequest request1 = new GetIndexRequest(indexName);
        // 2.发送请求
        boolean exists = esClient.indices().exists(request1, RequestOptions.DEFAULT);
        // 3.输出
        System.err.println(exists ? "索引库已经存在!" : "索引库不存在!");
        if (exists){
            AcknowledgedResponse response = esClient.indices().delete(request, RequestOptions.DEFAULT);
            delFlag = response.isAcknowledged();
            System.out.println("删除成功");
        }
        return delFlag;
    }

    /**
     * 新增文档数据
     * @param indexName
     * @param json
     * @param id
     * @throws IOException
     */
    public void addDocument(String indexName,String json,String id) throws IOException {
        // 1.准备Request对象
        IndexRequest request = new IndexRequest(indexName).id(id);
        // 2.准备Json文档
        request.source(json, XContentType.JSON);
        // 3.发送请求
        IndexResponse response =esClient.index(request, RequestOptions.DEFAULT);
        System.out.println(response.status());
    }

    /**
     * 批量新增数据
     * @param list
     * @param indexName
     * @param id
     * @throws IOException
     */
    public void testBulkDocument(List<String> list,String indexName,String id) throws IOException {
        // 1.准备Request
        BulkRequest request = new BulkRequest();
        // 2.准备数据
        for (String json : list){
            request.add(new IndexRequest(indexName)
                    .id(id)
                    .source(json,XContentType.JSON));
        }
        // 3.发送请求
        BulkResponse bulk = esClient.bulk(request,RequestOptions.DEFAULT);
        System.out.println(bulk.status());// ok
    }

    /**
     * 更新文档内容
     * @param indexName
     * @param json
     * @param id
     * @throws IOException
     */
    public void updateDocument(String indexName,String json,String id) throws IOException {
        // 1.准备Request
        UpdateRequest request = new UpdateRequest(indexName, id);
        // 2.准备请求参数
        request.doc(json,XContentType.JSON);
        // 3.发送请求
        UpdateResponse response = esClient.update(request, RequestOptions.DEFAULT);
        System.out.println(response.status()); // OK
    }

    /**
     * 根据id 获取详情
     * @param indexName
     * @param id
     * @return
     * @throws IOException
     */
    public String getDocumentById(String indexName,String id) throws IOException {
        // 1.准备Request
        GetRequest request = new GetRequest(indexName, id);
        // 2.发送请求,得到响应
        GetResponse response = esClient.get(request, RequestOptions.DEFAULT);
        // 3.解析响应结果
        String json = response.getSourceAsString();
        return json;
    }

    /**
     * 根据id删除文档
     * @param indexName
     * @param id
     * @throws IOException
     */
    public void deleteDocument(String indexName,String id) throws IOException {
        // 1.准备Request
        DeleteRequest request = new DeleteRequest(indexName, id);
        // 2.发送请求
        DeleteResponse response = esClient.delete(request, RequestOptions.DEFAULT);
        System.out.println(response.status());// OK
    }

    /**
     * 查询所有
     * @param indexName
     * @return
     * @throws IOException
     */
    public SearchHit[] matchAll(String indexName) throws IOException {
        // 1 创建request对象
        SearchRequest request = new SearchRequest(indexName);
        // 2 准备参数 :DSL语句
        request.source().query(QueryBuilders.matchAllQuery());
        // 3.发送请求
        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        // 4. 解析
        SearchHits searchHits = response.getHits();
        // 获取总条数
        long total = searchHits.getTotalHits().value;
        // 获取文档数组
        SearchHit[] hits = searchHits.getHits();
        return hits;
    }

    /**
     * 根据名称查询文档数据
     * @param indexName
     * @param name
     * @param text
     * @return
     * @throws IOException
     */
    public SearchHit[] match(String indexName,String name,String text) throws IOException {
        // 1 创建request对象
        SearchRequest request = new SearchRequest(indexName);
        // 2 准备参数 :DSL语句
        request.source().query(QueryBuilders.matchQuery(name,text));
        // 3.发送请求
        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        // 4. 解析
        SearchHits searchHits = response.getHits();
        // 获取总条数
        long total = searchHits.getTotalHits().value;
        // 获取文档数组
        SearchHit[] hits = searchHits.getHits();
        return hits;
    }

    /**
     * 排序分页查询
     * @param indexName
     * @param pageNum
     * @param pageSize
     * @return
     * @throws IOException
     */
    public SearchHit[] testPageSort(String indexName,int pageNum,int pageSize) throws IOException {
        // 1 创建request对象
        SearchRequest request = new SearchRequest(indexName);
        // 2 准备参数 :DSL语句
        request.source().query(QueryBuilders.matchAllQuery());
        // 排序
//        request.source().sort("price", SortOrder.ASC);
        request.source().from((pageNum-1)*5).size(pageSize);
        // 3.发送请求
        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        // 4. 解析
        SearchHits searchHits = response.getHits();
        // 获取总条数
        long total = searchHits.getTotalHits().value;
        // 获取文档数组
        SearchHit[] hits = searchHits.getHits();
        return hits;
    }

    /**
     *高亮显示
     * @param indexName
     * @param name
     * @param text
     * @return
     * @throws IOException
     */
    public SearchHit[] testHighLight(String indexName,String name,String text) throws IOException {
        // 1 创建request对象
        SearchRequest request = new SearchRequest(indexName);
        // 2 准备参数 :DSL语句
        request.source().query(QueryBuilders.matchQuery(name,text));
        request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
        // 3.发送请求
        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        // 4. 解析
        SearchHits searchHits = response.getHits();
        // 获取总条数
        long total = searchHits.getTotalHits().value;
        // 获取文档数组
        SearchHit[] hits = searchHits.getHits();
        return hits;
    }
	/**
     * 搜索文档内容解析方法
     * 其中HotelDoc为json转对象的实体类 需更具实际自定义
     * @param response
     */
    private void handleResponse(SearchResponse response) {
        SearchHits searchHits = response.getHits();
        // 获取总条数
        long total = searchHits.getTotalHits().value;
        // 获取文档数组
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit searchHit : hits) {
            // 获取json
            String json = searchHit.getSourceAsString();
            // json 转对象
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            // 获取高亮结果
            Map<String, HighlightField> highlightFieldMap = searchHit.getHighlightFields();
            if (!CollectionUtils.isEmpty(highlightFieldMap)){
                // 更具字段名获取高亮结果
                HighlightField highlightField = highlightFieldMap.get("name");
                if (highlightField!=null){
                    // 获取高亮的值
                    String name = highlightField.getFragments()[0].toString();
                    // 覆盖高亮结果
                    hotelDoc.setName(name);
                }
            }
            System.out.println(hotelDoc);
        }
    }
}

新建测试

import com.alibaba.fastjson.JSON;
import com.sh.common.elasticsearch.config.ESProperties;
import com.sh.common.elasticsearch.util.EsUtils;
import com.sh.system.api.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import org.junit.jupiter.api.Test;

@SpringBootTest
public class SpringbootTest {

    @Autowired
    private ESProperties esProperties;

    @Autowired
    private EsUtils esUtils;

    @Test
    void testMatchAll() throws IOException {
       System.out.println(esUtils.getDocumentById("hotel","47066"));
    }
}

打印如下
在这里插入图片描述

微服务中使用

目录结构如下
springboot集成elasticsearch7.6版本,以及在微服务中的使用_第4张图片

需编写spring.factories来加载bean类!!

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.sh.common.elasticsearch.config.ElasticsearchConfig,\
  com.sh.common.elasticsearch.util.EsUtils,\
  com.sh.common.elasticsearch.config.ESProperties

然后在另一个项目中直接加载该包

<dependency>
     <groupId>com.sh</groupId>
     <artifactId>sh-common-elasticsearch</artifactId>
     <version>3.4.0</version>
 </dependency>

你可能感兴趣的:(elasticsearch,springboot,java)