0


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

文章目录

⛄引言

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

一、酒店搜索和分页

⛅需求分析

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

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

在这里插入图片描述

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

在这里插入图片描述

请求参数如下:

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

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

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

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

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

⚡源码编写

定义实体类

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

importlombok.Data;@DatapublicclassRequestParams{privateString key;privateInteger page;privateInteger size;privateString sortBy;}

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

import lombok.Data;import java.util.List;

@Data
publicclassPageResult{private Long total;private List<HotelDoc> hotels;publicPageResult(){}publicPageResult(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")publicclassHotelController{@AutowiredprivateIHotelService hotelService;// 搜索酒店数据@PostMapping("/list")publicPageResultsearch(@RequestBodyRequestParams params){return hotelService.search(params);}}

实现搜索业务

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

1)在

cn.itcast.hotel.service

中的

IHotelService

接口中定义一个方法:

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

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

项目

中的

HotelDemoApplication

中声明这个Bean:

@BeanpublicRestHighLevelClientclient(){returnnewRestHighLevelClient(RestClient.builder(HttpHost.create("http://IP地址:9200")));}

3)在

service.impl

中的

HotelService

中实现search方法:

@OverridepublicPageResultsearch(RequestParams params){try{// 1.准备RequestSearchRequest request =newSearchRequest("hotel");// 2.准备DSL// 2.1.queryString 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.解析响应returnhandleResponse(response);}catch(IOException e){thrownewRuntimeException(e);}}// 结果解析privatePageResulthandleResponse(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 =newArrayList<>();for(SearchHit hit : hits){// 获取文档sourceString json = hit.getSourceAsString();// 反序列化HotelDoc hotelDoc = JSON.parseObject(json,HotelDoc.class);// 放入集合
        hotels.add(hotelDoc);}// 4.4.封装返回returnnewPageResult(total, hotels);}

二、酒店结果过滤

⌚需求分析

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

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

在这里插入图片描述

请求参数如下:

在这里插入图片描述

包含的过滤条件有:

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

我们需要做两件事情:

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

修改实体类

@DatapublicclassRequestParams{privateString key;privateInteger page;privateInteger size;privateString sortBy;// 下面是新增的过滤条件参数privateString city;privateString brand;privateString starName;privateInteger minPrice;privateInteger maxPrice;}

⏰修改搜索业务

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

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

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

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

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

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

在这里插入图片描述

buildBasicQuery 函数如下:

privatevoidbuildBasicQuery(RequestParams params,SearchRequest request){// 1.构建BooleanQueryBoolQueryBuilder 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);}

再次重启运行即可。

✅效果图

在这里插入图片描述

⛵小结

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

技术改变世界!!!

**

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


本文转载自: https://blog.csdn.net/weixin_45526437/article/details/130819519
版权归原作者 Bug 终结者 所有, 如有侵权,请联系我们删除。

“Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 搜索、分页与结果过滤”的评论:

还没有评论