赞
踩
本文参考黑马 分布式Elastic search
Elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容
实现黑马旅游的酒店搜索功能,完成关键字搜索和分页
在项目首页,有一个很大的搜索框、也有分页按钮

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

请求参数如下:
{
"key": "",
"page": 1,
"size": 5,
"sortBy": "default"
}
由此可以知道,我们这个请求的信息如下:
total:总条数List<HotelDoc>:当前页的数据因此,我们实现业务的流程如下:
定义实体类
实体类有两个,一个是前端的请求参数实体,一个是服务端应该返回的响应结果实体。
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,声明查询接口,满足下列要求:
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); }
需求: 添加品牌、城市、星级、价格等过滤功能
在页面搜索框下,会有几个过滤条件:

请求参数如下:

包含的过滤条件有:
我们需要做两件事情:
修改实体类
@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查询,根据关键字搜索,现在要添加条件过滤,包括:
多个查询条件组合,肯定是boolean查询来组合:
因为条件构建的逻辑比较复杂,这里先封装为一个函数:

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); }
再次重启运行即可。

以上就是【Bug 终结者】对 Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 搜索、分页与结果过滤 的简单介绍,ES搜索引擎无疑是最优秀的分布式搜索引擎,使用它,可大大提高项目的灵活、高效性! 技术改变世界!!!
如果这篇【文章】有帮助到你,希望可以给【Bug 终结者】点个赞
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/35548
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。