0


Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 我附近的、酒店竞排

文章目录

⛄引言

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

一、我附近的酒店

⛅需求分析

在酒店列表页的右侧,有一个小地图,点击地图的定位按钮,地图会找到你所在的位置:

在这里插入图片描述

点击定位后,会发送给服务端以下请求json

在这里插入图片描述

我们要做的事情就是基于这个location坐标,然后按照距离对周围酒店排序。实现思路如下:

  • 修改RequestParams参数,接收location字段
  • 修改search方法业务逻辑,如果location有值,添加根据geo_distance排序的功能

⚡源码编写

修改实体类

importlombok.Data;@DatapublicclassRequestParams{privateString key;privateInteger page;privateInteger size;privateString sortBy;privateString city;privateString brand;privateString starName;privateInteger minPrice;privateInteger maxPrice;// 我当前的地理坐标privateString location;}

距离排序

我们以前学习过排序功能,包括两种:

  • 普通字段排序
  • 地理坐标排序

地理坐标 DSL 语法如下

GET/indexName/_search
{"query":{"match_all":{}},"sort":[{"price":"asc"},{"_geo_distance":{"FIELD":"纬度,经度","order":"asc","unit":"km"}}]}

添加距离排序

@OverridepublicPageResultsearch(RequestParams params){try{// 1.准备RequestSearchRequest request =newSearchRequest("hotel");// 2.准备DSL// 2.1.querybuildBasicQuery(params, request);// 2.2.分页int page = params.getPage();int size = params.getSize();
        request.source().from((page -1)* size).size(size);// 2.3.排序String location = params.getLocation();if(location !=null&&!location.equals("")){
            request.source().sort(SortBuilders.geoDistanceSort("location",newGeoPoint(location)).order(SortOrder.ASC).unit(DistanceUnit.KILOMETERS));}// 3.发送请求SearchResponse response = client.search(request,RequestOptions.DEFAULT);// 4.解析响应returnhandleResponse(response);}catch(IOException e){thrownewRuntimeException(e);}}

排序距离展示

重启进行测试:

在这里插入图片描述

的却可以实现 我附近的酒店距离排序,但是没有展示距离我们有多远,这个我们应该怎么实现呢?

排序完成后,页面还要获取我附近每个酒店的具体距离值,这个值在响应结果中是独立的:

在这里插入图片描述

因此,我们在结果解析阶段,除了解析source部分以外,还要得到sort部分,也就是排序的距离,然后放到响应结果中。

我们要做两件事:

  • 修改HotelDoc,添加排序距离字段,用于页面显示
  • 修改HotelService类中的handleResponse方法,添加对sort值的获取

添加距离排序字段

importlombok.Data;importlombok.NoArgsConstructor;@Data@NoArgsConstructorpublicclassHotelDoc{privateLong id;privateString name;privateString address;privateInteger price;privateInteger score;privateString brand;privateString city;privateString starName;privateString business;privateString location;privateString pic;// 排序时的 距离值privateObject distance;publicHotelDoc(Hotel hotel){this.id = hotel.getId();this.name = hotel.getName();this.address = hotel.getAddress();this.price = hotel.getPrice();this.score = hotel.getScore();this.brand = hotel.getBrand();this.city = hotel.getCity();this.starName = hotel.getStarName();this.business = hotel.getBusiness();this.location = hotel.getLatitude()+", "+ hotel.getLongitude();this.pic = hotel.getPic();}}

修改 handleResponse 方法

在这里插入图片描述

重启进行测试

在这里插入图片描述

已成功展示距离。

二、酒店竞价排名

需求:让指定的酒店在搜索结果中排名置顶

⌚需求分析

要让指定酒店在搜索结果中排名置顶,效果如图:

在这里插入图片描述

页面会给指定的酒店添加广告标记。

那怎样才能让指定的酒店排名置顶呢?

我们之前学习过的function_score查询可以影响算分,算分高了,自然排名也就高了。而function_score包含3个要素:

  • 过滤条件:哪些文档要加分
  • 算分函数:如何计算function score
  • 加权方式:function score 与 query score如何运算

这里的需求是:让指定酒店排名靠前。因此我们需要给这些酒店添加一个标记,这样在过滤条件中就可以根据这个标记来判断,是否要提高算分

比如,我们给酒店添加一个字段:isAD,Boolean类型:

  • true:是广告
  • false:不是广告

这样function_score包含3个要素就很好确定了:

  • 过滤条件:判断isAD 是否为true
  • 算分函数:我们可以用最简单暴力的weight,固定加权值
  • 加权方式:可以用默认的相乘,大大提高算分

因此,业务的实现步骤包括:

  1. 给HotelDoc类添加isAD字段,Boolean类型
  2. 挑选几个你喜欢的酒店,给它的文档数据添加isAD字段,值为true
  3. 修改search方法,添加function score功能,给isAD值为true的酒店增加权重

⏰修改搜索业务

添加广告标记

修改实体类

importlombok.Data;importlombok.NoArgsConstructor;@Data@NoArgsConstructorpublicclassHotelDoc{privateLong id;privateString name;privateString address;privateInteger price;privateInteger score;privateString brand;privateString city;privateString starName;privateString business;privateString location;privateString pic;privateObject distance;// 加入广告标识privateBoolean isAD;publicHotelDoc(Hotel hotel){this.id = hotel.getId();this.name = hotel.getName();this.address = hotel.getAddress();this.price = hotel.getPrice();this.score = hotel.getScore();this.brand = hotel.getBrand();this.city = hotel.getCity();this.starName = hotel.getStarName();this.business = hotel.getBusiness();this.location = hotel.getLatitude()+", "+ hotel.getLongitude();this.pic = hotel.getPic();}}

随便设置几个作为广告置项

POST/hotel/_update/2056105938{"doc":{"isAD":true}}POST/hotel/_update/38609{"doc":{"isAD":true}}

添加算分函数查询

接下来我们就要修改查询条件了。之前是用的boolean 查询,现在要改成function_socre查询。

function_score查询结构如下:

在这里插入图片描述

对应的JavaAPI如下:

在这里插入图片描述

我们可以将之前写的boolean查询作为原始查询条件放到query中,接下来就是添加过滤条件算分函数加权模式了。所以原来的代码依然可以沿用。

加入算分查询

privatevoidbuildBasicQuery(RequestParams params,SearchRequest request){// 1.构建BooleanQueryBoolQueryBuilder boolQuery =QueryBuilders.boolQuery();// 关键字搜索String key = params.getKey();if(key ==null||"".equals(key)){
        boolQuery.must(QueryBuilders.matchAllQuery());}else{
        boolQuery.must(QueryBuilders.matchQuery("all", key));}// 城市条件if(params.getCity()!=null&&!params.getCity().equals("")){
        boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));}// 品牌条件if(params.getBrand()!=null&&!params.getBrand().equals("")){
        boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand()));}// 星级条件if(params.getStarName()!=null&&!params.getStarName().equals("")){
        boolQuery.filter(QueryBuilders.termQuery("starName", params.getStarName()));}// 价格if(params.getMinPrice()!=null&& params.getMaxPrice()!=null){
        boolQuery.filter(QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));}// 2.算分控制FunctionScoreQueryBuilder functionScoreQuery =QueryBuilders.functionScoreQuery(// 原始查询,相关性算分的查询
        boolQuery,// function score的数组newFunctionScoreQueryBuilder.FilterFunctionBuilder[]{// 其中的一个function score 元素newFunctionScoreQueryBuilder.FilterFunctionBuilder(// 过滤条件QueryBuilders.termQuery("isAD",true),// 算分函数ScoreFunctionBuilders.weightFactorFunction(10))});
    request.source().query(functionScoreQuery);}

效果展示

在这里插入图片描述

✅效果图

在这里插入图片描述

⛵小结

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

技术改变世界!!!

**

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


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

“Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 我附近的、酒店竞排”的评论:

还没有评论