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);
     }
 }
相关推荐
ai小陈4 小时前
GPU服务器租用存储验收:检查点写入与磁盘吞吐实战
运维·服务器·人工智能·ai·ssh·gpu算力
有毒的教程6 小时前
VMware仅主机模式:物理机 ↔ 虚拟机 文件共享
运维
山岚的运维笔记8 小时前
ComfyUI NVIDIA安装教程:官方便携版下载+run_nvidia_gpu.bat启动,8G显存Windows实操
运维·服务器·windows·笔记·prompt·aigc·comfyui
海宇大数据9 小时前
零信任架构实战:基于海宇活体识别V步骤1构建自动化远程公证会话初始化网关
运维·人工智能·架构·自动化
lisanmengmeng9 小时前
Nagios邮件报警的配置
linux·运维·服务器
Ruiery10 小时前
Linux 6.6内核 CPU 深度解析(六):cpufreq
linux·运维·服务器
天远数科10 小时前
零信任架构实战:基于天远全能消金报告构建自动化消费分期网关
运维·人工智能·架构·自动化
硅基手札10 小时前
【linux内核专栏 08】时间与定时器
linux·运维·服务器
想做小南娘,发现自己是女生喵11 小时前
Linux之Ubuntu入门篇知识总结
linux·运维·服务器
帷幕落秋12 小时前
Redis哨兵模式
运维·数据库