Elasticsearch封装公共索引增删改查

什么是索引?

  • 定义:索引是 Elasticsearch 中用于存储数据的逻辑命名空间。它由多个文档组成,每个文档是一个 JSON 格式的结构化数据
  • 对应关系:在关系数据库中,索引类似于表;而在 Elasticsearch 中,索引则相当于数据库的集合或目录。

依赖

选择方案一

使用这个依赖的话必须搭配配置类去使用

 <!-- elasticsearch -->
            <dependency>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
                <version>7.7.0</version>
            </dependency>
            <dependency>
                <groupId>org.elasticsearch.client</groupId>
                <artifactId>elasticsearch-rest-high-level-client</artifactId>
                <version>7.7.0</version>
            </dependency>

选择方案二

使用这个依赖的话配置类可写可不写,因为springboot工程已经帮我们自动的去完成配置了,不需要我们自己写了

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

配置

es:
  host: 111.229.0.43
  port: 9200
  scheme: http

配置类

package com.macro.mall.demo.config;

import lombok.Data;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Data
@Component
public class InitEsRes {

    @Value("${es.host}")
    private String host;
    @Value("${es.port}")
    private int port;
    @Value("${es.scheme}")
    private String scheme;

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        return new RestHighLevelClient(
                RestClient.builder(new HttpHost(host,port,scheme))
        );
    }
}

dto

package com.macro.mall.demo.dto;

import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;

/**
 * @Author:xsp
 * @Description: es索引传输对象
 * @name:EsIndexDto
 * @Date:2024/10/16 15:30
 */
@Data
public class EsIndexDto {
    /**
     * 索引名称
     */
    @NotEmpty(message = "索引名称不能为空")
    @ApiModelProperty(value = "索引名称", required = true, example = "。。。。")
    private String indexName;
    /**
     * 索引映射
     */
    @ApiModelProperty(value = "索引映射", required = true, example = "。。。。")
    private String indexMappings;
    /**
     * 索引配置
     */
    @ApiModelProperty(value = "索引配置", required = true, example = "。。。。")
    private String indexSettings;

}

controller

package com.macro.mall.demo.controller;

import com.macro.mall.common.api.CommonResult;
import com.macro.mall.demo.dto.EsIndexDto;
import com.macro.mall.demo.service.EsIndexService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jakarta.validation.constraints.NotEmpty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * @Author:xsp
 * @Description: es索引管理
 * @name:EsController
 * @Date:2024/10/15 20:38
 */
@RestController
@RequestMapping("/index")
@Validated
@Api(tags = "es索引管理")
public class EsIndexController {
    @Autowired
    private EsIndexService esIndexService;

    /**
     * 创建索引的接口
     * @param esIndexDto 索引信息
     * @return
     */
    @ApiOperation(value = "创建索引")
    @PostMapping("/create")
    public CommonResult createIndex(@Validated @RequestBody EsIndexDto esIndexDto) {
         esIndexService.createIndex(esIndexDto);
        return CommonResult.successMessage("索引创建成功"); // 调用服务方法创建索引
    }
    /**
     * 删除索引的接口
     * @param indexName 索引名称
     * @return
     */
    @ApiOperation(value = "删除索引")
    @DeleteMapping("/delete")
    public CommonResult deleteIndex(@RequestParam @NotEmpty(message = "索引名称不能为空") String indexName) {
        esIndexService.deleteIndex(indexName); // 调用服务方法删除索引
        return CommonResult.successMessage("索引删除成功");
    }

    /**
     *  获取索引的接口
     * @param indexName 索引名称
     * @return
     */
    @ApiOperation(value = "获取索引映射")
    @GetMapping("/get")
    public CommonResult<Map<String, Object>> getIndex(@RequestParam  @NotEmpty(message = "索引名称不能为空") String indexName) {
        Map<String, Object> indexMappings = esIndexService.getIndex(indexName);
        return CommonResult.success(indexMappings); // 调用服务方法获取索引
    }


    /**
     * 根据索引名称修改索引配置
     * @param esIndexDto 索引信息
     * @return
     */
    @ApiOperation(value = "修改索引配置")
    @PutMapping("/update")
    public CommonResult updateIndex(@Validated @RequestBody EsIndexDto esIndexDto) {
        esIndexService.updateIndex(esIndexDto);
        return CommonResult.successMessage("索引更新成功"); // 调用服务方法更新索引
    }
    /**
     * 判断索引是否存在
     * @param indexName 索引名称
     * @return
     */
    @ApiOperation(value = "判断索引是否存在")
    @GetMapping("/exists")
    public CommonResult exists(@RequestParam  @NotEmpty(message = "索引名称不能为空") String indexName) {
        boolean exists =esIndexService.exists(indexName);
        return CommonResult.success(exists);
    }
}

serveice

package com.macro.mall.demo.service;

import com.macro.mall.demo.dto.EsDocDto;
import com.macro.mall.demo.dto.EsIndexDto;

import java.util.List;
import java.util.Map;

/**
 * @Author:xsp
 * @Description:
 * @name:EsService
 * @Date:2024/10/15 20:39
 */
public interface EsDocService {
    /**
     * 批量添加
     * @param esDocDto 文档信息
     */
    void batchAdd(EsDocDto esDocDto);

    /**
     * 批量删除
     * @param indexName 索引名称
     * @param ids 多个id
     */
    void batchDelete(String indexName,  List<String> ids);
}

impl

package com.macro.mall.demo.service.impl;

import com.macro.mall.demo.dto.EsDocDto;
import com.macro.mall.demo.dto.EsIndexDto;
import com.macro.mall.demo.service.EsIndexService;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * @Author:xsp
 * @Description:
 * @name:EsServiceImpl
 * @Date:2024/10/15 20:39
 */
@Service
@Slf4j
public class EsIndexServiceImpl implements EsIndexService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;
    /**
     * 创建索引
     *
     * @param esIndexDto 索引信息
     */
    @Override
    public void createIndex(EsIndexDto esIndexDto) {
        // 检查索引是否已存在
        if (exists(esIndexDto.getIndexName())) {
            throw new RuntimeException("索引已经存在: " + esIndexDto.getIndexName());
        }

        // 创建索引请求
        CreateIndexRequest request = new CreateIndexRequest(esIndexDto.getIndexName());

        // 设置索引配置
        if (StringUtils.isNotBlank(esIndexDto.getIndexMappings())) {
            request.settings("_doc",esIndexDto.getIndexMappings(), XContentType.JSON);
        }

        // 执行创建索引操作
        try {
            restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
            log.info("索引创建成功: {}", esIndexDto.getIndexName());
        } catch (Exception e) {
            log.error("创建索引失败, 错误信息: {}", e.getMessage());
            throw new RuntimeException("创建索引失败: " + esIndexDto.getIndexName(), e);
        }
    }

    /**
     * 删除索引
     *
     * @param indexName 索引名称
     */
    @Override
    public void deleteIndex(String indexName) {
        // 检查索引是否存在
        if (!exists(indexName)) {
            throw new RuntimeException("索引不存在: " + indexName);
        }

        // 创建删除索引请求
        DeleteIndexRequest request = new DeleteIndexRequest(indexName);

        // 执行删除索引操作
        try {
            restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
            log.info("索引删除成功: {}", indexName);
        } catch (Exception e) {
            log.error("删除索引失败, 错误信息: {}", e.getMessage());
            throw new RuntimeException("删除索引失败: " + indexName, e);
        }
    }

    /**
     * 获取索引映射
     *
     * @param indexName 索引名称
     * @return 索引映射信息
     */
    @Override
    public Map<String, Object> getIndex(String indexName) {
        // 检查索引是否存在
        if (!exists(indexName)) {
            throw new RuntimeException("索引不存在: " + indexName);
        }

        // 创建获取索引请求
        GetIndexRequest request = new GetIndexRequest(indexName);

        // 执行获取索引映射操作
        try {
            GetIndexResponse response = restHighLevelClient.indices().get(request, RequestOptions.DEFAULT);
            log.info("获取索引映射成功: {}", indexName);
            return response.getMappings().get(indexName).sourceAsMap(); // 返回索引映射
        } catch (Exception e) {
            log.error("获取索引映射失败, 错误信息: {}", e.getMessage());
            throw new RuntimeException("获取索引映射失败: " + indexName, e);
        }
    }

    /**
     * 更新索引配置
     *
     * @param esIndexDto 索引信息
     */
    @Override
    public void updateIndex(EsIndexDto esIndexDto) {
        // 检查索引是否存在
        if (!exists(esIndexDto.getIndexName())) {
            throw new RuntimeException("索引不存在: " + esIndexDto.getIndexName());
        }

        // 创建更新索引设置请求
        UpdateSettingsRequest request = new UpdateSettingsRequest(esIndexDto.getIndexName());

        // 更新索引映射
        if (StringUtils.isNotBlank(esIndexDto.getIndexMappings())) {
            request.settings(esIndexDto.getIndexMappings(), XContentType.JSON);
        }

        // 执行更新索引设置操作
        try {
            boolean acknowledged = restHighLevelClient.indices().putSettings(request, RequestOptions.DEFAULT).isAcknowledged();
            if (acknowledged) {
                log.info("索引设置更新成功: {}", esIndexDto.getIndexName());
            } else {
                log.warn("索引设置更新未被确认: {}", esIndexDto.getIndexName());
            }
        } catch (Exception e) {
            log.error("更新索引设置失败, 错误信息: {}", e.getMessage());
            throw new RuntimeException("更新索引设置失败: " + esIndexDto.getIndexName(), e);
        }
    }

    /**
     * 判断索引是否存在
     *
     * @param indexName 索引名称
     * @return 索引是否存在
     */
    @Override
    public boolean exists(String indexName) {
        // 创建获取索引请求
        GetIndexRequest request = new GetIndexRequest(indexName);
        try {
            // 执行获取索引操作并返回索引是否存在
            boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
            log.info("判断索引是否存在: {}, 结果: {}", indexName, exists);
            return exists;
        } catch (Exception e) {
            log.error("判断索引是否存在失败, 错误信息: {}", e.getMessage());
            return false; // 返回判断失败
        }
    }


}

统一结果集

package com.macro.mall.common.api;

import cn.hutool.json.JSONUtil;

/**
 * 通用返回对象
 * Created by 9a8204a7-f77d-4ab8-ae70-b4721fef2f95 on 2019/4/19.
 */
public class CommonResult<T> {
    private long code;
    private String message;
    private T data;

    protected CommonResult() {
    }

    protected CommonResult(long code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    /**
     * 成功返回信息
     * @param message 提示信息
     */
    public static <T> CommonResult<T> successMessage(String message) {
        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, null);
    }
    /**
     * 成功返回结果
     *
     * @param data 获取的数据
     */
    public static <T> CommonResult<T> success(T data) {
        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);
    }

    /**
     * 成功返回结果
     *
     * @param data 获取的数据
     * @param  message 提示信息
     */
    public static <T> CommonResult<T> success(T data, String message) {
        return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);
    }


    /**
     * 失败返回结果
     * @param errorCode 错误码
     */
    public static <T> CommonResult<T> failed(IErrorCode errorCode) {
        return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);
    }

    /**
     * 失败返回结果
     * @param errorCode 错误码
     * @param message 错误信息
     */
    public static <T> CommonResult<T> failed(IErrorCode errorCode,String message) {
        return new CommonResult<T>(errorCode.getCode(), message, null);
    }

    /**
     * 失败返回结果
     * @param message 提示信息
     */
    public static <T> CommonResult<T> failed(String message) {
        return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);
    }

    /**
     * 失败返回结果
     */
    public static <T> CommonResult<T> failed() {
        return failed(ResultCode.FAILED);
    }

    /**
     * 参数验证失败返回结果
     */
    public static <T> CommonResult<T> validateFailed() {
        return failed(ResultCode.VALIDATE_FAILED);
    }

    /**
     * 参数验证失败返回结果
     * @param message 提示信息
     */
    public static <T> CommonResult<T> validateFailed(String message) {
        return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);
    }

    /**
     * 未登录返回结果
     */
    public static <T> CommonResult<T> unauthorized(T data) {
        return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
    }

    /**
     * 未授权返回结果
     */
    public static <T> CommonResult<T> forbidden(T data) {
        return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
    }

    public long getCode() {
        return code;
    }

    public void setCode(long code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return JSONUtil.toJsonStr(this);
    }
}

这里我用的是这个统一结果集,结合自己实际情况去使用相对应的统一结果集

Spring原生效验异常

    @ResponseBody
    @ExceptionHandler(value = ApiException.class)
    public CommonResult handle(ApiException e) {
        if (e.getErrorCode() != null) {
            return CommonResult.failed(e.getErrorCode());
        }
        return CommonResult.failed(e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public CommonResult handleValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                message = fieldError.getField()+fieldError.getDefaultMessage();
            }
        }
        return CommonResult.validateFailed(message);
    }

    @ResponseBody
    @ExceptionHandler(value = BindException.class)
    public CommonResult handleValidException(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                message = fieldError.getField()+fieldError.getDefaultMessage();
            }
        }
        return CommonResult.validateFailed(message);
    }

    /**
     * 最大异常
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public CommonResult handle(Exception e) {
        e.printStackTrace();
        return CommonResult.validateFailed(e.getMessage());
    }

这里我是用的这几个写的异常捕获器,结合自己实际情况去使用相对应的异常捕获

目前先更新到这里,后期补发

相关推荐
java1234_小锋7 小时前
Elasticsearch是如何实现Master选举的?
大数据·elasticsearch·搜索引擎
AiFlutter9 小时前
Java实现简单的搜索引擎
java·搜索引擎·mybatis
梦幻通灵13 小时前
ES分词环境实战
大数据·elasticsearch·搜索引擎
Elastic 中国社区官方博客13 小时前
Elasticsearch 中的热点以及如何使用 AutoOps 解决它们
大数据·运维·elasticsearch·搜索引擎·全文检索
infiniteWei16 小时前
【Lucene】搜索引擎和文档相关性评分 BM25 算法的工作原理
算法·搜索引擎·lucene
小黑屋说YYDS18 小时前
ElasticSearch7.x入门教程之索引概念和基础操作(三)
elasticsearch
Java 第一深情20 小时前
Linux上安装单机版ElasticSearch6.8.1
linux·elasticsearch·全文检索
KevinAha1 天前
Elasticsearch 6.8 分析器
elasticsearch
wuxingge2 天前
elasticsearch7.10.2集群部署带认证
运维·elasticsearch
Elastic 中国社区官方博客2 天前
Elasticsearch:如何部署文本嵌入模型并将其用于语义搜索
大数据·人工智能·elasticsearch·搜索引擎·ai·全文检索