什么是索引?
- 定义:索引是 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());
}
这里我是用的这几个写的异常捕获器,结合自己实际情况去使用相对应的异常捕获
目前先更新到这里,后期补发