SpringBoot集成ElasticSearch

ES实战

效果

实现关键字搜索并高亮关键字

在线体验:http://www.sixkey-world.top

导入依赖

复制代码
 <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
 </dependency>

配置文件

复制代码
 spring:
   elasticsearch:
     uris: http://47.96.73.90:9200
     # 连接超时时间(默认1s)
     connection-timeout: 10s

ES客户端配置

复制代码
 /**
  * ElasticSearch 客户端配置
  */
 @Configuration
 public class RestClientConfig extends AbstractElasticsearchConfiguration {
     @Bean
     @Override
     public RestHighLevelClient elasticsearchClient() {
         final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                 .connectedTo("host:9200")
                 .build();
         return RestClients.create(clientConfiguration).rest();
     }
 }

ES实体类

复制代码
 /**
  * ES中的商品实体类
  * @author author
  * @since 2023-11-14
  */
 @Data
 @Document(indexName = "qs_goods")
 public class EsGoodsDto{
 ​
     @Id
     @Field(type = FieldType.Keyword)
     private Integer key;
 ​
     @Field(type = FieldType.Keyword)
     private Integer storeId;
 ​
     @Field(type = FieldType.Text,analyzer = "ik_max_word")
     private String store;
 ​
     @Field(index=false,type = FieldType.Keyword)
     private String storeImage;
 ​
     @Field(type = FieldType.Text,analyzer = "ik_max_word")
     private String name;
 ​
     @Field(type = FieldType.Double)
     private double price;
 ​
     @Field(index = false,type = FieldType.Integer)
     private Integer sale;
 ​
     @Field(index=false,type = FieldType.Keyword)
     private String image;
 }

ES Repository

复制代码
 /**
  * 方便创建索引库,项目启动后自动创建实体类
  */
 @Repository
 public interface EsGoodsDtoRepository extends ElasticsearchRepository<EsGoodsDto,String> {
 }

ES常用方法

复制代码
 /**
  * 封装ES的一些常用方法
  * @Author: @weixueshi
  * @Create: 2023/12/29 - 10:11
  * @Version: v1.0
  */
 @Service
 public class EsGoodsService {
 ​
     @Autowired
     private RestHighLevelClient client;
 ​
     /**
      * 批量导入商品数据
      * @param list
      */
     public void bulkSaveGoods(List<EsGoodsDto> list) throws IOException {
         BulkRequest bulkRequest = new BulkRequest();
         list.stream().forEach(goods -> {
             bulkRequest.add(new IndexRequest(EsConstant.INDEX_NAME_GOODS)
                     .id(goods.getKey().toString())
                     .source(JSON.toJSONString(goods),XContentType.JSON));
         });
         client.bulk(bulkRequest, RequestOptions.DEFAULT);
     }
 ​
     /**
      * 封装数据
      * @param response
      * @return
      */
     private List<EsGoodsDto> handlerResponse(SearchResponse response) {
         SearchHits searchHits = response.getHits();
         SearchHit[] hits = searchHits.getHits();
         List<EsGoodsDto> list = new ArrayList<EsGoodsDto>();
         for(SearchHit hit : hits){
             String json = hit.getSourceAsString();
             EsGoodsDto esGoodsDto = JSON.parseObject(json, EsGoodsDto.class);
             list.add(esGoodsDto);
         }
         return list;
     }
 ​
     /**
      * 返回搜索匹配到的商品id
      * @param param
      * @return
      * @throws IOException
      */
     public List<Integer> frontSearchList(String param,String selectMsg) throws IOException {
         SearchRequest request = new SearchRequest(EsConstant.INDEX_NAME_GOODS);
         if(StringUtils.isBlank(param)){
             return null;
         }else{
             if(EsConstant.GOODS_NAME.equalsIgnoreCase(selectMsg)){
                 //按商品名称搜索
                 request.source().query(QueryBuilders.multiMatchQuery(param,"name"));
                 SearchResponse response = client.search(request, RequestOptions.DEFAULT);
                 //处理返回数据
                 List<EsGoodsDto> list = handlerResponse(response);
                 List<Integer> goodsIds = list.stream().map(EsGoodsDto::getKey).collect(Collectors.toList());
                 return goodsIds;
             } else if (EsConstant.STORE_NAME.equalsIgnoreCase(selectMsg)) {
                 //按店铺名称搜索
                 request.source().query(QueryBuilders.multiMatchQuery(param,"store"));
                 SearchResponse response = client.search(request, RequestOptions.DEFAULT);
                 //处理返回数据
                 List<EsGoodsDto> list = handlerResponse(response);
                 List<Integer> storeIds = list.stream().map(EsGoodsDto::getStoreId).collect(Collectors.toList());
                 return storeIds;
             }
         }
         return null;
     }
 ​
     /**
      * 商品搜索
      * @param pageNo
      * @param pageSize
      * @param ids
      * @return
      */
     public Map<String, Object> searchGoodsFrontList(Integer pageNo, Integer pageSize, List<Integer> ids,String name) throws IOException {
         if(!CollectionUtils.isEmpty(ids)){
             SearchRequest request = new SearchRequest(EsConstant.INDEX_NAME_GOODS);
             //根据key查询
             request.source().query(QueryBuilders.termsQuery("key",ids));
             request.source().query(QueryBuilders.multiMatchQuery(name,"name"));
             //高亮查询完成
             request.source().highlighter(new HighlightBuilder()
                     .field("name")
                     .preTags("<font color='red'>")
                     .postTags("</font>")
                     .requireFieldMatch(false));
             request.source().from((pageNo - 1) * pageSize).size(pageSize);
             SearchResponse response = client.search(request, RequestOptions.DEFAULT);
             //高亮处理返回数据
             List<EsGoodsDto> list = handlerGoodsLightResponse(response);
             Map<String,Object> map = new HashMap<String,Object>();
             map.put("data",list);
             map.put("total",response.getHits().getTotalHits().value);
             return map;
         }
         return null;
     }
 ​
     private List<EsGoodsDto> handlerGoodsLightResponse(SearchResponse response) {
         SearchHits searchHits = response.getHits();
         SearchHit[] hits = searchHits.getHits();
         List<EsGoodsDto> list = new ArrayList<EsGoodsDto>();
         for(SearchHit hit : hits){
             String json = hit.getSourceAsString();
             EsGoodsDto esGoodsDto = JSON.parseObject(json, EsGoodsDto.class);
             Map<String, HighlightField> highlightFields = hit.getHighlightFields();
             if(!CollectionUtils.isEmpty(highlightFields)){
                 HighlightField highlightField = highlightFields.get("name");
                 if(highlightField != null){
                     String name = highlightField.getFragments()[0].string();
                     esGoodsDto.setName(name);
                 }
             }
             list.add(esGoodsDto);
         }
         return list;
     }
 ​
     /**
      * 新增商品文档
      * @param esGoodsDto
      * @throws IOException
      */
     public void addDocument(EsGoodsDto esGoodsDto) throws IOException {
         IndexRequest indexRequest = new IndexRequest(EsConstant.INDEX_NAME_GOODS).id(esGoodsDto.getKey().toString());
         indexRequest.source(JSON.toJSONString(esGoodsDto),XContentType.JSON);
         client.index(indexRequest,RequestOptions.DEFAULT);
     }
 ​
     /**
      * 删除文档
      * @param list
      * @throws IOException
      */
     public void deleteDocument(List<Integer> list,String indexName) throws IOException {
         BulkRequest bulkRequest = new BulkRequest();
         list.stream().forEach(id -> {
             bulkRequest.add(new DeleteRequest(indexName,id.toString()));
         });
         client.bulk(bulkRequest, RequestOptions.DEFAULT);
     }
 ​
     /**
      * 删除索引库
      * @throws IOException
      */
     public void deleteIndex(String indexName) throws IOException {
         DeleteIndexRequest deleteRequest = new DeleteIndexRequest(indexName);
         client.indices().delete(deleteRequest,RequestOptions.DEFAULT);
     }
 ​
     /**
      * 判断索引库是否存在
      * @return
      * @throws IOException
      */
     public boolean isExits(String indexName) throws IOException {
         GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
         return client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
     }
 }
相关推荐
礼拜天没时间.6 分钟前
《Docker实战入门与部署指南:从核心概念到网络与数据管理》:环境准备与Docker安装
运维·网络·docker·容器·centos
每天瞎忙的农民工8 分钟前
Ubuntu 24 安装npm22
linux·运维·ubuntu·npm
j_xxx404_23 分钟前
Linux:进程控制(创建/终止/等待/获取退出信息/多进程)
linux·运维·服务器
BUG_MeDe36 分钟前
LINUX MTU/MSS(1500 1460等)的一些理解
linux·运维·服务器
曹牧37 分钟前
Nginx:正向代理与反向代理
运维·nginx
Ha_To38 分钟前
2026.1.30 搭建docker仓库
运维·docker·容器
lpfasd12341 分钟前
Docker Desktop 在国内使用的囧境:镜像拉取失败、加速器失效与破局之道
运维·docker·容器
江湖有缘1 小时前
Docker部署SurveyKing调查问卷系统和考试系统
运维·docker·容器
小小管写大大码10 小时前
如何让vscode变得更智能?vscode接入claude实现自动编程
运维·ide·vscode·自动化·编辑器·ai编程·腾讯云ai代码助手
zhang1338308907511 小时前
CG-09H 超声波风速风向传感器 加热型 ABS材质 重量轻 没有机械部件
大数据·运维·网络·人工智能·自动化