Bootstrap

Elsaticsearch java基本操作

索引 基本操作
package com.orchids.elasticsearch.web.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.orchids.elasticsearch.web.po.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
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.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.client.indices.GetIndexResponse;
import org.elasticsearch.cluster.metadata.MappingMetadata;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;

/**
 * @ Author qwh
 * @ Date 2024/7/12 19:18
 */
@Slf4j
@Api(tags = "索引")
@RestController
@RequestMapping("/elastic/index")
@RequiredArgsConstructor
public class ElasticIndexController {
    private final RestHighLevelClient client;
    static final String MAPPING_TEMPLATE = "{\n" +
    "  \"mappings\": {\n" +
    "    \"properties\": {\n" +
    "      \"name\":{\n" +
    "        \"type\": \"text\",\n" +
    "        \"analyzer\": \"ik_max_word\"\n" +
    "      },\n" +
    "      \"age\":{\n" +
    "        \"type\": \"integer\"\n" +
    "      },\n" +
    "      \"sex\":{\n" +
    "        \"type\": \"text\"\n" +
    "      }\n" +
    "    }\n" +
    "  }\n" +
    "}";
    @ApiOperation("添加索引")
    @PostMapping("/add")
    public String CreateIndex(@RequestParam("index") String index) throws IOException {
        CreateIndexRequest request = new CreateIndexRequest(index);
        request.source(MAPPING_TEMPLATE, XContentType.JSON);
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        log.error("response{}",response);
        if (response!=null){
            return "add index success";
        }else {
            return "add index fail";
        }
    }
    @ApiOperation("获取索引")
    @GetMapping("/get")
    public Map<String, Object> GetIndex(@RequestParam("index") String index) throws IOException {
        //创建请求对象
        GetIndexRequest request = new GetIndexRequest(index);
        //发送请求
        GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
        // todo 健壮性
        if (client.indices().exists(request,RequestOptions.DEFAULT)){
            MappingMetadata data = response.getMappings().get(index);
            return data.getSourceAsMap();
        }else {
            return null;
        }
    }
    /**
     * 查看指定索引的映射信息。
     * <p>
     * 通过该接口,可以获取Elasticsearch中指定索引的映射设置。映射(Mapping)定义了字段的类型和分析器等配置,
     * 对于查询和分析数据至关重要。此方法接收一个索引名称作为参数,返回该索引的映射配置。
     *
     * @param index 指定的索引名称,用于获取该索引的映射信息。
     * @return 包含指定索引映射配置的Map对象。
     * @throws IOException 如果获取映射信息时发生I/O错误。
     */
    @ApiOperation("查看映射")
    @GetMapping("/mapper")
    public Map<String, Object> Index(@RequestParam("index") String index) throws IOException {
        // todo 健壮性
        // 创建GetIndexRequest对象,指定要获取映射信息的索引。
        GetIndexRequest request = new GetIndexRequest(index);
        // 执行请求,获取索引的映射响应。
        GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
        // 从响应中提取映射配置。
        Map<String, MappingMetadata> mappings = response.getMappings();
        // 获取指定索引的映射元数据。
        MappingMetadata metadata = mappings.get(index);
        // 从映射元数据中提取源映射配置。
        Map<String, Object> source = metadata.getSourceAsMap();
        // 返回源映射配置。
        return source;
    }
    @ApiOperation("删除索引")
    @DeleteMapping("/del")
    public String  DeleteIndex(@RequestParam("index") String index) throws IOException {
        //创建请求对象
        DeleteIndexRequest request = new DeleteIndexRequest(index);
        //发送请求
        return client.indices().delete(request, RequestOptions.DEFAULT)!=null ? index+"删除成功" : index+"删除失败";
    }

}

文档
package com.orchids.elasticsearch.web.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.orchids.elasticsearch.web.po.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.bulk.BulkRequest;
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.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.web.bind.annotation.*;

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

/**
 * @ Author qwh
 * @ Date 2024/7/12 21:31
 */
@Slf4j
@Api(tags = "文档")
@RestController
@RequestMapping("/elastic/doc")
@RequiredArgsConstructor
public class ElasticDocumentController {
    private final RestHighLevelClient client;
    @ApiOperation("添加文档")
    @PostMapping("/add")
    public String addDocument(@RequestParam("index") String index, @RequestBody User user) throws IOException {
        if (user==null) {
            throw new RuntimeException("非法参数");
        }
        String jsonUser = JSONUtil.toJsonStr(user);
        System.out.println(jsonUser);
        //准备请求对象
        IndexRequest request = new IndexRequest(index).id(user.getName());
        //准备json文档
        request.source(jsonUser, XContentType.JSON);
        //发送请求 put
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        if (response!=null){
            return "success";
        }else {
            return "fail";
        }
    }
    @ApiOperation("获取文档")
    @GetMapping("/get")
    public User getDocument(@RequestParam("id") String id,@RequestParam("index") String index) throws IOException {
        //准备请求对象 参数:索引库 文档id
        GetRequest request = new GetRequest(index).id(id);
        //发送请求 得到json格式响应
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        String jsonBean = response.getSourceAsString();
        log.error("响应response{}",jsonBean);
        User bean = JSONUtil.toBean(jsonBean, User.class);
        System.out.println(bean);
        return bean;
    }
    @ApiOperation("所有文档")
    @GetMapping("/all")
    public List<User> allDocument(@RequestParam String index) throws IOException {
        //准备请求对象 参数索引
        SearchRequest request = new SearchRequest(index);
        //请求参数
        request.source().query(QueryBuilders.matchAllQuery());
        //发送请求 并返回响应
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //解析响应
        return handleResponse(response);
    }

    private List<User> handleResponse(SearchResponse response) {
        SearchHits searchHits = response.getHits();
        //获取总条数
        long total = searchHits.getTotalHits().value;
        log.error("一共搜索到{}条数据",total);
        //遍历数组
        SearchHit[] hits = searchHits.getHits();
        List<User> users = new LinkedList<>();
        for (SearchHit hit : hits) {
            //得到每一个数组的_source 原始的json文档
            String source = hit.getSourceAsString();
            log.error("原始的json格式{}",source);
            //反序列化
            User user = JSONUtil.toBean(source, User.class);
            log.error("放序列化后json格式{}",user);
            users.add(user);
        }
        return users;
    }

    @ApiOperation("删除文档")
    @DeleteMapping("/del")
    public String updateDocument(@RequestParam("index") String index,@RequestParam("id")String id) throws IOException {
        //request
        DeleteRequest request = new DeleteRequest(index,id);
        //修改内容
        DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);
        if (delete!=null){
            return "success";
        }else {
            return "fail";
        }
    }
    @ApiOperation("修改文档")
    @PostMapping("/update")
   public String updateDocument(@RequestParam("index") String index,@RequestBody User user) throws IOException {
        if (user.getName()==null) {
            return "id参数非法";
        }
        //request
        UpdateRequest request = new UpdateRequest(index,user.getName());
        //修改内容
        request.doc("name",user.getName(),"age",user.getAge(),"sex",user.getSex());
        //发送请求
        //当es中没有对应的id 添加该id

        try {
            //修改
            client.update(request, RequestOptions.DEFAULT);
        } catch (ElasticsearchStatusException e) {
            //添加
            String jsonUser = JSONUtil.toJsonStr(user);
            System.out.println(jsonUser);
            //准备请求对象
            IndexRequest req = new IndexRequest(index).id(user.getName());
            //准备json文档
            req.source(jsonUser, XContentType.JSON);
            //添加
            client.index(req,RequestOptions.DEFAULT);
        }
        return "修改成功";
    }
    @ApiOperation("批量添加")
    @PutMapping("/adds")
    public String LoadDocument() throws IOException {
        return "todo";
//        int current = 1;
//        int size = 100;
//        while (true){
//            Page<User> page = new Page<>(current, size);
//            List<User> users = page.getRecords();
//            if (CollUtil.isEmpty(users)) {
//                return null;
//            }
//            log.info("加载第{}页数据共{}条", current, users.size());
//            //创建request
//            BulkRequest request = new BulkRequest("user");
//            //准备参数
//            for (User user : users) {
//
//    /*            IndexRequest indexRequest = new IndexRequest().id(user.getName());
//                indexRequest.source(JSONUtil.toJsonStr(user),XContentType.JSON);
//                request.add(indexRequest);*/
//
//                request.add(new IndexRequest().id(user.getName()).source(JSONUtil.toJsonStr(user), XContentType.JSON));
//            }
//            client.bulk(request, RequestOptions.DEFAULT);
//            current++;
//        }
    }
}

Java client
package com.orchids.elasticsearch.web.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.orchids.elasticsearch.web.po.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.web.bind.annotation.*;

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

/**
 * @ Author qwh
 * @ Date 2024/7/12 21:48
 */
@Slf4j
@Api(tags = "Restapi")
@RestController
@RequestMapping("/elastic/rest")
@RequiredArgsConstructor
public class ElasticRestController {
    private final RestHighLevelClient client;
//    @GetMapping()
    public void testAgg() throws IOException {
        // 1.创建Request
        SearchRequest request = new SearchRequest("items");
        // 2.准备请求参数
        BoolQueryBuilder bool = QueryBuilders.boolQuery()
                .filter(QueryBuilders.termQuery("category", "手机"))
                .filter(QueryBuilders.rangeQuery("price").gte(300000));
        request.source().query(bool).size(0);
        // 3.聚合参数
        request.source().aggregation(
                AggregationBuilders.terms("brand_agg").field("brand").size(5)
        );
        // 4.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 5.解析聚合结果
        Aggregations aggregations = response.getAggregations();
        // 5.1.获取品牌聚合
        Terms brandTerms = aggregations.get("brand_agg");
        // 5.2.获取聚合中的桶
        List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
        // 5.3.遍历桶内数据
        for (Terms.Bucket bucket : buckets) {
            // 5.4.获取桶内key
            String brand = bucket.getKeyAsString();
            System.out.print("brand = " + brand);
            long count = bucket.getDocCount();
            System.out.println("; count = " + count);
        }
    }
    @ApiOperation("高亮查询")
    @GetMapping("/high") //high ok
    public List<User> HighlightQuery(
            @ApiParam(name = "index",value = "索引",required = true) @RequestParam("index")String index,
            @ApiParam(name = "high",value = "高亮条件",required = true)@RequestParam("high") String high ) throws IOException {
        // 1.创建Request
        SearchRequest request = new SearchRequest(index);
        // 2.组织请求参数
        // 2.1.query条件
        request.source().query(QueryBuilders.matchQuery("name", high));
        // 2.2.高亮条件
        request.source().highlighter(
                SearchSourceBuilder.highlight()
                        .field("name")
                        .preTags("<em>")
                        .postTags("</em>")
        );
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        return hand(response);
    }
    private List<User> hand(SearchResponse response) {
        SearchHits searchHits = response.getHits();
        // 1.获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 2.遍历结果数组
        SearchHit[] hits = searchHits.getHits();
        List<User> result = new LinkedList<>();
        for (SearchHit hit : hits) {
            // 3.得到_source,也就是原始json文档
            String source = hit.getSourceAsString();
            // 4.反序列化
            User user = JSONUtil.toBean(source, User.class);
            // 5.获取高亮结果
            Map<String, HighlightField> hfs = hit.getHighlightFields();
            if (CollUtil.isNotEmpty(hfs)) {
                // 5.1.有高亮结果,获取name的高亮结果
                HighlightField hf = hfs.get("name");
                if (hf != null) {
                    // 5.2.获取第一个高亮结果片段,就是商品名称的高亮值
                    String hfName = hf.getFragments()[0].string();
                    user.setName(hfName);
                }
            }
            result.add(user);
        }
        return result;
    }
    @ApiOperation("分页查询")
    @GetMapping("/page")
    public List <User> pageQuery(
            @ApiParam(value = "索引",required = true)@RequestParam("index")String index,
            @ApiParam(value = "字段条件",required = true)@RequestParam("field") String field,
            @ApiParam(value = "当前页",required = true)@RequestParam("current")String current,
            @ApiParam(value = "页大小",required = true)@RequestParam("size")String size) throws IOException {

        // 1.创建Request
        SearchRequest request = new SearchRequest(index);
        // 2.组织请求参数
        // 2.1.搜索条件参数
        request.source().query(QueryBuilders.matchQuery("name", field));
        // 2.2.排序参数
        request.source().sort("age", SortOrder.ASC);
        // 2.3.分页参数
        request.source().from((Integer.valueOf(current) - 1) * Integer.valueOf(size)).size(Integer.valueOf(size));
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        return handleResponse(response);

    }
    private List <User> handleResponse(SearchResponse response) {
        SearchHits searchHits = response.getHits();
        // 1.获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 2.遍历结果数组
        SearchHit[] hits = searchHits.getHits();
        List<User> result = new LinkedList<>();
        for (SearchHit hit : hits) {
            // 3.得到_source,也就是原始json文档
            String source = hit.getSourceAsString();
            // 4.反序列化并打印
            User user = JSONUtil.toBean(source, User.class);
            result.add(user);
        }
        return result;
    }
    @ApiOperation("复合条件")
    @GetMapping("/compare")
    public List<User> compareQuery(
            @ApiParam(value = "索引",required = true)@RequestParam("index") String index,
            @ApiParam(value = "名称",required = true)@RequestParam ("name")String name,
            @ApiParam(value = "性别",required = true)@RequestParam("sex") String sex,
            @ApiParam(value = "年龄",required = true)@RequestParam("age") String age)throws IOException {
        // 1.创建Request
        SearchRequest request = new SearchRequest(index);
        // 2.组织请求参数
        // 2.1.准备bool查询
        BoolQueryBuilder bool = QueryBuilders.boolQuery();
        // 2.2.关键字搜索
        if (name!=null){
            bool.must(QueryBuilders.matchQuery("name", name));
        }
        if (sex!=null){
            // 2.3.品牌过滤
            bool.filter(QueryBuilders.termQuery("sex", sex));
        }
        // 2.4.价格过滤  gt >
        if (age!=null){
            bool.filter(QueryBuilders.rangeQuery("age").gt(age));
        }
        request.source().query(bool);
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        return handleResponse(response);
    }
    @ApiOperation("区间查询")
    @GetMapping("/term")//term
    public List<User> rangeQuery(
            @ApiParam(value = "索引",required = true)@RequestParam String index,
            @ApiParam(value = "左区间",required = true)@RequestParam("gt") String gt,
            @ApiParam(value = "右区间",required = true)@RequestParam("lt") String lt,
            @ApiParam(value = "支持排序的字段",required = true)@RequestParam("field") String field) throws IOException {
        //创建request
        SearchRequest request = new SearchRequest(index);
        //请求参数
        //todo 健壮性
        request.source().query(QueryBuilders.rangeQuery(field).gte(gt).lte(lt));
        //解析相应
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
       return handleResponse(response);
    }
    @ApiOperation("多条件查询")
    @GetMapping("/multi_match")//multi_match todo 待探讨
    public List<User> multi_matchQuery(@ApiParam(value = "包含条件1" ,required = true)@RequestParam("name1") String args1,
                                       @ApiParam(value = "包含条件2",required = true)@RequestParam("name2") String args2) throws IOException {
        //创建request
        SearchRequest request = new SearchRequest("user");
        //请求参数
        request.source().query(QueryBuilders.multiMatchQuery("name",args1,args2));
        //解析相应
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        return handleResponse(response);
    }
    @ApiOperation("match查询")
    @GetMapping("/match")//match ok
    public List<User> matchQuery(
            @ApiParam(value = "索引",name = "index",required = true) @RequestParam("index")String index,
            @ApiParam(value ="匹配字段",name = "field",required = true)@RequestParam("field") String field) throws IOException {
        //创建request
        SearchRequest request = new SearchRequest(index);
        //请求参数
        request.source().query(QueryBuilders.matchQuery("name",field));
        //解析相应
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        return handleResponse(response);
    }
    @ApiOperation("match-all查询")
    @GetMapping("/match-all")//match-all ok
    public List<User> SearchMatchAll(@ApiParam(value = "索引",name = "index",required = true) @RequestParam("index")String index) throws IOException {
        //创建request
        SearchRequest request = new SearchRequest(index);
        //请求参数
        request.source().query(QueryBuilders.matchAllQuery());
        //解析相应
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        return handleResponse(response);
    }
}

Bean
package com.orchids.elasticsearch.web.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @ Author qwh
 * @ Date 2024/7/12 21:16
 */
@Configuration
public class RestClientConfiguration {
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        return new RestHighLevelClient(RestClient.builder(HttpHost.create("http://localhost:9200")));
    }
}

po
package com.orchids.elasticsearch.web.po;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;

import java.io.Serializable;

/**
 * @ Author qwh
 * @ Date 2024/7/12 20:20
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@ApiModel(description = "索引库实体")
public class User implements Serializable {
    @ApiModelProperty(value = "名字",name = "name",example = "二哈")
//    @NonNull
    private String name;
//    @NonNull
    @ApiModelProperty(value = "年龄",name = "age",example = "99")
    private Integer age;
//    @NonNull
    @ApiModelProperty(value = "性别",name = "sex",example = "男")
    private String sex;

}

app
package com.orchids.elasticsearch;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class ElasticsearchApplication {

    public static void main(String[] args) {
        SpringApplication.run(ElasticsearchApplication.class, args);
    }

}

配置类

server:
  port: 8080
logging:
  level:
    web: info
  pattern:
    dateformat: HH:mm:ss:SSS
  file:
    path: "logs"
knife4j:
  enable: true
  openapi:
    title: 接口文档
    description: "接口文档"
    email: [email protected]
    concat: erha
    url: https://www.orchids.love
    version: v1.0.0
    group:
      default:
        group-name: default
        api-rule: package
        api-rule-resources: com.orchids.elasticsearch.web
        
依赖
<?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>
  <groupId>com.orchids</groupId>
  <artifactId>elasticsearch</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>elasticsearch</name>
  <description>elasticsearch</description>
  <properties>
    <java.version>1.8</java.version>
    <elasticsearch.version>7.12.1</elasticsearch.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <spring-boot.version>2.7.12</spring-boot.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.elasticsearch</groupId>
      <artifactId>elasticsearch</artifactId>
      <version>${elasticsearch.version}</version>
    </dependency>
    <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-client</artifactId>
      <version>${elasticsearch.version}</version>
    </dependency>
    <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-high-level-client</artifactId>
      <version>${elasticsearch.version}</version>
    </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>
    </dependency>
    <dependency>
      <groupId>com.github.xiaoymin</groupId>
      <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
      <version>4.1.0</version>
    </dependency>
    <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-json</artifactId>
      <version>5.8.28</version>
    </dependency>
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.5.6</version>
    </dependency>
  </dependencies>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring-boot.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.orchids.elasticsearch.ElasticsearchApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

;