關(guān)于Elasticsearch封裝公共索引增刪改查
什么是索引?
- 定義:索引是 Elasticsearch 中用于存儲(chǔ)數(shù)據(jù)的邏輯命名空間。它由多個(gè)文檔組成,每個(gè)文檔是一個(gè) JSON 格式的結(jié)構(gòu)化數(shù)據(jù)
- 對(duì)應(yīng)關(guān)系:在關(guān)系數(shù)據(jù)庫(kù)中,索引類似于表;而在 Elasticsearch 中,索引則相當(dāng)于數(shù)據(jù)庫(kù)的集合或目錄。
依賴
選擇方案一
使用這個(gè)依賴的話必須搭配配置類去使用
<!-- 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>
選擇方案二
使用這個(gè)依賴的話配置類可寫(xiě)可不寫(xiě),因?yàn)閟pringboot工程已經(jīng)幫我們自動(dòng)的去完成配置了,不需要我們自己寫(xiě)了
<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索引傳輸對(duì)象 * @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; /** * 創(chuàng)建索引的接口 * @param esIndexDto 索引信息 * @return */ @ApiOperation(value = "創(chuàng)建索引") @PostMapping("/create") public CommonResult createIndex(@Validated @RequestBody EsIndexDto esIndexDto) { esIndexService.createIndex(esIndexDto); return CommonResult.successMessage("索引創(chuàng)建成功"); // 調(diào)用服務(wù)方法創(chuàng)建索引 } /** * 刪除索引的接口 * @param indexName 索引名稱 * @return */ @ApiOperation(value = "刪除索引") @DeleteMapping("/delete") public CommonResult deleteIndex(@RequestParam @NotEmpty(message = "索引名稱不能為空") String indexName) { esIndexService.deleteIndex(indexName); // 調(diào)用服務(wù)方法刪除索引 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); // 調(diào)用服務(wù)方法獲取索引 } /** * 根據(jù)索引名稱修改索引配置 * @param esIndexDto 索引信息 * @return */ @ApiOperation(value = "修改索引配置") @PutMapping("/update") public CommonResult updateIndex(@Validated @RequestBody EsIndexDto esIndexDto) { esIndexService.updateIndex(esIndexDto); return CommonResult.successMessage("索引更新成功"); // 調(diào)用服務(wù)方法更新索引 } /** * 判斷索引是否存在 * @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 多個(gè)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; /** * 創(chuàng)建索引 * * @param esIndexDto 索引信息 */ @Override public void createIndex(EsIndexDto esIndexDto) { // 檢查索引是否已存在 if (exists(esIndexDto.getIndexName())) { throw new RuntimeException("索引已經(jīng)存在: " + esIndexDto.getIndexName()); } // 創(chuàng)建索引請(qǐng)求 CreateIndexRequest request = new CreateIndexRequest(esIndexDto.getIndexName()); // 設(shè)置索引配置 if (StringUtils.isNotBlank(esIndexDto.getIndexMappings())) { request.settings(esIndexDto.getIndexMappings(), XContentType.JSON); } // 執(zhí)行創(chuàng)建索引操作 try { restHighLevelClient.indices().create(request, RequestOptions.DEFAULT); log.info("索引創(chuàng)建成功: {}", esIndexDto.getIndexName()); } catch (Exception e) { log.error("創(chuàng)建索引失敗, 錯(cuò)誤信息: {}", e.getMessage()); throw new RuntimeException("創(chuàng)建索引失敗: " + esIndexDto.getIndexName(), e); } } /** * 刪除索引 * * @param indexName 索引名稱 */ @Override public void deleteIndex(String indexName) { // 檢查索引是否存在 if (!exists(indexName)) { throw new RuntimeException("索引不存在: " + indexName); } // 創(chuàng)建刪除索引請(qǐng)求 DeleteIndexRequest request = new DeleteIndexRequest(indexName); // 執(zhí)行刪除索引操作 try { restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT); log.info("索引刪除成功: {}", indexName); } catch (Exception e) { log.error("刪除索引失敗, 錯(cuò)誤信息: {}", 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); } // 創(chuàng)建獲取索引請(qǐng)求 GetIndexRequest request = new GetIndexRequest(indexName); // 執(zhí)行獲取索引映射操作 try { GetIndexResponse response = restHighLevelClient.indices().get(request, RequestOptions.DEFAULT); log.info("獲取索引映射成功: {}", indexName); return response.getMappings().get(indexName).sourceAsMap(); // 返回索引映射 } catch (Exception e) { log.error("獲取索引映射失敗, 錯(cuò)誤信息: {}", e.getMessage()); throw new RuntimeException("獲取索引映射失敗: " + indexName, e); } } /** * 更新索引配置 * * @param esIndexDto 索引信息 */ @Override public void updateIndex(EsIndexDto esIndexDto) { // 檢查索引是否存在 if (!exists(esIndexDto.getIndexName())) { throw new RuntimeException("索引不存在: " + esIndexDto.getIndexName()); } // 創(chuàng)建更新索引設(shè)置請(qǐng)求 UpdateSettingsRequest request = new UpdateSettingsRequest(esIndexDto.getIndexName()); // 更新索引映射 if (StringUtils.isNotBlank(esIndexDto.getIndexMappings())) { request.settings(esIndexDto.getIndexMappings(), XContentType.JSON); } // 執(zhí)行更新索引設(shè)置操作 try { boolean acknowledged = restHighLevelClient.indices().putSettings(request, RequestOptions.DEFAULT).isAcknowledged(); if (acknowledged) { log.info("索引設(shè)置更新成功: {}", esIndexDto.getIndexName()); } else { log.warn("索引設(shè)置更新未被確認(rèn): {}", esIndexDto.getIndexName()); } } catch (Exception e) { log.error("更新索引設(shè)置失敗, 錯(cuò)誤信息: {}", e.getMessage()); throw new RuntimeException("更新索引設(shè)置失敗: " + esIndexDto.getIndexName(), e); } } /** * 判斷索引是否存在 * * @param indexName 索引名稱 * @return 索引是否存在 */ @Override public boolean exists(String indexName) { // 創(chuàng)建獲取索引請(qǐng)求 GetIndexRequest request = new GetIndexRequest(indexName); try { // 執(zhí)行獲取索引操作并返回索引是否存在 boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT); log.info("判斷索引是否存在: {}, 結(jié)果: {}", indexName, exists); return exists; } catch (Exception e) { log.error("判斷索引是否存在失敗, 錯(cuò)誤信息: {}", e.getMessage()); return false; // 返回判斷失敗 } } }
統(tǒng)一結(jié)果集
package com.macro.mall.common.api; import cn.hutool.json.JSONUtil; /** * 通用返回對(duì)象 * 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); } /** * 成功返回結(jié)果 * * @param data 獲取的數(shù)據(jù) */ public static <T> CommonResult<T> success(T data) { return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data); } /** * 成功返回結(jié)果 * * @param data 獲取的數(shù)據(jù) * @param message 提示信息 */ public static <T> CommonResult<T> success(T data, String message) { return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data); } /** * 失敗返回結(jié)果 * @param errorCode 錯(cuò)誤碼 */ public static <T> CommonResult<T> failed(IErrorCode errorCode) { return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null); } /** * 失敗返回結(jié)果 * @param errorCode 錯(cuò)誤碼 * @param message 錯(cuò)誤信息 */ public static <T> CommonResult<T> failed(IErrorCode errorCode,String message) { return new CommonResult<T>(errorCode.getCode(), message, null); } /** * 失敗返回結(jié)果 * @param message 提示信息 */ public static <T> CommonResult<T> failed(String message) { return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null); } /** * 失敗返回結(jié)果 */ public static <T> CommonResult<T> failed() { return failed(ResultCode.FAILED); } /** * 參數(shù)驗(yàn)證失敗返回結(jié)果 */ public static <T> CommonResult<T> validateFailed() { return failed(ResultCode.VALIDATE_FAILED); } /** * 參數(shù)驗(yàn)證失敗返回結(jié)果 * @param message 提示信息 */ public static <T> CommonResult<T> validateFailed(String message) { return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null); } /** * 未登錄返回結(jié)果 */ public static <T> CommonResult<T> unauthorized(T data) { return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data); } /** * 未授權(quán)返回結(jié)果 */ 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); } }
這里我用的是這個(gè)統(tǒng)一結(jié)果集,結(jié)合自己實(shí)際情況去使用相對(duì)應(yīng)的統(tǒng)一結(jié)果集
Spring原生效驗(yàn)異常
@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()); }
這里我是用的這幾個(gè)寫(xiě)的異常捕獲器,結(jié)合自己實(shí)際情況去使用相對(duì)應(yīng)的異常捕獲
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot項(xiàng)目中通過(guò)@Value給參數(shù)賦值失敗的解決方案
springboot項(xiàng)目中通過(guò)@Value給屬性附值失敗,給參數(shù)賦值失敗,打印為空值,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),對(duì)大家解決問(wèn)題有一定的幫助,需要的朋友可以參考下2024-04-04java 中的instanceof用法詳解及instanceof是什么意思(推薦)
instanceof 是 Java 的保留關(guān)鍵字。它的作用是測(cè)試它左邊的對(duì)象是否是它右邊的類的實(shí)例,返回 boolean 的數(shù)據(jù)類型。接下來(lái)通過(guò)本文給大家介紹java 中的instanceof用法詳解及instanceof是什么意思,需要的朋友參考下吧2017-11-11Mybatis?Interceptor線程安全引發(fā)的bug問(wèn)題
這篇文章主要介紹了Mybatis?Interceptor線程安全引發(fā)的bug問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02解決使用@RequestParam注解和泛型遇到的問(wèn)題
這篇文章主要介紹了解決使用@RequestParam注解和泛型遇到的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10Spring?Cloud?Alibaba微服務(wù)組件Sentinel實(shí)現(xiàn)熔斷限流
這篇文章主要為大家介紹了Spring?Cloud?Alibaba微服務(wù)組件Sentinel實(shí)現(xiàn)熔斷限流過(guò)程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06