Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 搜索、分页与结果过滤

Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 搜索、分页与结果过滤,第1张

⛄引言

本文参考黑马 分布式Elastic search
Elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容

一、酒店搜索和分页

⛅需求分析

实现黑马旅游的酒店搜索功能,完成关键字搜索和分页

在项目首页,有一个很大的搜索框、也有分页按钮

Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 搜索、分页与结果过滤,在这里插入图片描述,第2张

点击搜索按钮,可以看到浏览器控制台 网络发出了请求

Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 搜索、分页与结果过滤,在这里插入图片描述,第3张

请求参数如下:

{ "key": "", "page": 1, "size": 5, "sortBy": "default" }

由此可以知道,我们这个请求的信息如下:

  • 请求方式:POST
  • 请求路径:/hotel/list
  • 请求参数:JSON对象,包含4个字段:
    • key:搜索关键字
    • page:页码
    • size:每页大小
    • sortBy:排序,目前暂不实现
  • 返回值:分页查询,需要返回分页结果PageResult,包含两个属性:
    • total

      :总条数
    • List<HotelDoc>

      :当前页的数据

因此,我们实现业务的流程如下:

  • 步骤一:定义实体类,接收请求参数的JSON对象
  • 步骤二:编写controller,接收页面的请求
  • 步骤三:编写业务实现,利用RestHighLevelClient实现搜索、分页

⚡源码编写

定义实体类

实体类有两个,一个是前端的请求参数实体,一个是服务端应该返回的响应结果实体。

import lombok.Data;@Data public class RequestParams { private String key; private Integer page; private Integer size; private String sortBy; }

定义返回值对象,由于要实现分页,所以需要定义。

import lombok.Data;import java.util.List;@Data public class PageResult { private Long total; private List<HotelDoc> hotels; public PageResult() { } public PageResult(Long total, List<HotelDoc> hotels) { this.total = total; this.hotels = hotels; } }

定义Controller 控制层

定义一个HotelController,声明查询接口,满足下列要求:

  • 请求方式:Post
  • 请求路径:/hotel/list
  • 请求参数:对象,类型为RequestParam
  • 返回值:PageResult,包含两个属性
    • Long total

      :总条数
    • List<HotelDoc> hotels

      :酒店数据

@RestController @RequestMapping("/hotel") public class HotelController { @Autowired private IHotelService hotelService; // 搜索酒店数据 @PostMapping("/list") public PageResult search(@RequestBody RequestParams params){ return hotelService.search(params); } }

实现搜索业务

我们在controller调用了IHotelService,并没有实现该方法,因此下面我们就在IHotelService中定义方法,并且去实现业务逻辑。

1)在

cn.itcast.hotel.service

中的

IHotelService

接口中定义一个方法:

/** * 根据关键字搜索酒店信息 * @param params 请求参数对象,包含用户输入的关键字 * @return 酒店文档列表 */ PageResult search(RequestParams params);

2)实现搜索业务,肯定离不开RestHighLevelClient,我们需要把它注册到Spring中作为一个Bean。在

项目

中的

HotelDemoApplication

中声明这个Bean:

@Bean public RestHighLevelClient client(){ return new RestHighLevelClient(RestClient.builder( HttpHost.create("http://IP地址:9200") )); }

3)在

service.impl

中的

HotelService

中实现search方法:

@Override public PageResult search(RequestParams params) { try { // 1.准备Request SearchRequest request = new SearchRequest("hotel"); // 2.准备DSL // 2.1.query String key = params.getKey(); if (key == null || "".equals(key)) { boolQuery.must(QueryBuilders.matchAllQuery()); } else { boolQuery.must(QueryBuilders.matchQuery("all", key)); } // 2.2.分页 int page = params.getPage(); int size = params.getSize(); request.source().from((page - 1) * size).size(size); // 3.发送请求 SearchResponse response = client.search(request, RequestOptions.DEFAULT); // 4.解析响应 return handleResponse(response); } catch (IOException e) { throw new RuntimeException(e); } }// 结果解析 private PageResult handleResponse(SearchResponse response) { // 4.解析响应 SearchHits searchHits = response.getHits(); // 4.1.获取总条数 long total = searchHits.getTotalHits().value; // 4.2.文档数组 SearchHit[] hits = searchHits.getHits(); // 4.3.遍历 List<HotelDoc> hotels = new ArrayList<>(); for (SearchHit hit : hits) { // 获取文档source String json = hit.getSourceAsString(); // 反序列化 HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class); // 放入集合 hotels.add(hotelDoc); } // 4.4.封装返回 return new PageResult(total, hotels); }

二、酒店结果过滤

⌚需求分析

需求: 添加品牌、城市、星级、价格等过滤功能

在页面搜索框下,会有几个过滤条件:

Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 搜索、分页与结果过滤,在这里插入图片描述,第4张

请求参数如下:

Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 搜索、分页与结果过滤,在这里插入图片描述,第5张

包含的过滤条件有:

  • brand:品牌值
  • city:城市
  • minPrice~maxPrice:价格范围
  • starName:星级

我们需要做两件事情:

  • 修改请求参数的对象RequestParams,接收上述参数
  • 修改业务逻辑,在搜索条件之外,添加一些过滤条件

修改实体类

@Data public class RequestParams { private String key; private Integer page; private Integer size; private String sortBy; // 下面是新增的过滤条件参数 private String city; private String brand; private String starName; private Integer minPrice; private Integer maxPrice; }

⏰修改搜索业务

在HotelService的search方法中,只有一个地方需要修改:requet.source().query( … )其中的查询条件。

在之前的业务中,只有match查询,根据关键字搜索,现在要添加条件过滤,包括:

  • 品牌过滤:是keyword类型,用term查询
  • 星级过滤:是keyword类型,用term查询
  • 价格过滤:是数值类型,用range查询
  • 城市过滤:是keyword类型,用term查询

多个查询条件组合,肯定是boolean查询来组合:

  • 关键字搜索放到must中,参与算分
  • 其它过滤条件放到filter中,不参与算分

因为条件构建的逻辑比较复杂,这里先封装为一个函数:

Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 搜索、分页与结果过滤,在这里插入图片描述,第6张

buildBasicQuery 函数如下:

private void buildBasicQuery(RequestParams params, SearchRequest request) { // 1.构建BooleanQuery BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); // 2.关键字搜索 String key = params.getKey(); if (key == null || "".equals(key)) { boolQuery.must(QueryBuilders.matchAllQuery()); } else { boolQuery.must(QueryBuilders.matchQuery("all", key)); } // 3.城市条件 if (params.getCity() != null && !params.getCity().equals("")) { boolQuery.filter(QueryBuilders.termQuery("city", params.getCity())); } // 4.品牌条件 if (params.getBrand() != null && !params.getBrand().equals("")) { boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand())); } // 5.星级条件 if (params.getStarName() != null && !params.getStarName().equals("")) { boolQuery.filter(QueryBuilders.termQuery("starName", params.getStarName())); } // 6.价格 if (params.getMinPrice() != null && params.getMaxPrice() != null) { boolQuery.filter(QueryBuilders .rangeQuery("price") .gte(params.getMinPrice()) .lte(params.getMaxPrice()) ); } // 7.放入source request.source().query(boolQuery); }

再次重启运行即可。

✅效果图

Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 搜索、分页与结果过滤,在这里插入图片描述,第7张

⛵小结

以上就是【Bug 终结者】对 Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 搜索、分页与结果过滤 的简单介绍,ES搜索引擎无疑是最优秀的分布式搜索引擎,使用它,可大大提高项目的灵活、高效性!

技术改变世界!!!

如果这篇【文章】有帮助到你,希望可以给【Bug 终结者】点个赞,创作不易,如果有对【后端技术】、【前端领域】感兴趣的小可爱,也欢迎关注❤️❤️❤️ 【Bug 终结者】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/13518065.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-12-19
下一篇 2023-12-23

发表评论

登录后才能评论

评论列表(0条)

保存