本文参考黑马 分布式Elastic search
Elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容
实现黑马旅游的酒店搜索功能,完成关键字搜索和分页
在项目首页,有一个很大的搜索框、也有分页按钮
点击搜索按钮,可以看到浏览器控制台 网络发出了请求
请求参数如下:
{ "key": "", "page": 1, "size": 5, "sortBy": "default" }
由此可以知道,我们这个请求的信息如下:
因此,我们实现业务的流程如下:
定义实体类
实体类有两个,一个是前端的请求参数实体,一个是服务端应该返回的响应结果实体。
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 Listhotels; public PageResult() { } public PageResult(Long total, List hotels) { this.total = total; this.hotels = hotels; } }
定义Controller 控制层
定义一个HotelController,声明查询接口,满足下列要求:
@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.遍历 Listhotels = 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 终结者】点个赞👍,创作不易,如果有对【后端技术】、【前端领域】感兴趣的小可爱,也欢迎关注❤️❤️❤️ 【Bug 终结者】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💝💝💝!