当前位置: 首页 > 后端技术 > Node.js

微服务SpringBoot集成RedisGEO实现附近商户功能

时间:2023-04-03 16:14:35 Node.js

?简介本文参考了点评项目中的黑马点评项目。如何实现附近商户的查询,显示距离你5公里以内的商户,这样的功能如何实现?答案是可以用Redis来实现。当然,可能有很多种实现方式。本文主要介绍如何使用Redis实现附近商户的搜索功能。1.RedisGEO数据结构使用?GEO基本语法,命令GEO是GeoLocation的简写形式,表示地理坐标。Redis在3.2版本增加了对GEO的支持,可以存储地理坐标信息,帮助我们根据经纬度检索数据。常用命令GEOADD:添加一个地理空间信息,包括:longitude(经度)、latitude(纬度)、value(成员)GEODIST:计算指定两点之间的距离并返回GEOHASH:将指定成员的坐标转换为Hash字符串格式并返回GEOPOS:返回指定成员的坐标GEORADIUS:指定圆的圆心和半径,找到圆内包含的所有成员,按照到圆心的距离排序,返回。6.GEOSSEARCH未来将被弃用:搜索指定范围内的成员,并返回它们按照与指定点的距离排序。范围可以是圆形或矩形。6.2.新函数GEOSEARCHSTORE:与GEOSEARCH功能相同,但结果可以存储在指定的key中。6.2.新功能?使用GEO存储经纬度和查询距离。这篇博文的Redis版本是6.2版。输入redis查询geo相关命令。使用GEO完成以下功能,实现两点距离查询,指定范围内的位置要求如下使用GEO添加北京(天安门广场116.39746939.908821,故宫116.39702739.918056,北海公园116.38997739.933144)查询距离天安门和故宫之间的经纬度在上面添加的地方中查询天安门广场(116.39782739.90374度)查看OGED附近OGED位置的指定经纬度OGED信息GEOHASH查看指定地址的经纬度HASH值扩展:GEOPOS和GEOHASH的区别在于GEOHASH保存了经纬度存储的内存,减少了不必要的内存消耗,从而提高了性能GEODIST查看天安门广场到故宫的距离GEOSEARCH查询天安门广场附近2公里的位置2.SpringBoot集成了Redis将商店数据导入GEO并编写SpringBoot单元测试以导入Redis数据@ResourceprivateIShopServiceshopService;@ResourceprivateStringRedisTemplatestringRedisTemplate;@TestvoidloadShopData(){//1.查询店铺信息ListshopList=shopService.list();//2.将店铺分组,按typeId分组,相同typeId放在一个集合中Map>map=shopList.stream().collect(Collectors.groupingBy(Shop::getTypeId));//3.批量写入redisfor(Map.Entry>entry:map.entrySet()){//3.1获取类型idLongtypeId=entry.getKey();Stringkey=RedisConstants.SHOP_GEO_KEY+typeId;//3.2获取同类型店铺的集合Listvalue=entry.getValue();List>locations=newArrayList<>(value.size());//3.3写入redisGEOADD键经度维度成员for(Shopshop:value){locations.add(newRedisGeoCommands.GeoLocation<>(shop.getId().toString(),newPoint(shop.getX(),shop.getY())));}stringRedisTemplate.opsForGeo().add(key,locations);}}复制代码运行,勾选Redis即可3.SpringBoot集成Redis实现附近商户功能黑马点评项目实现附近商户查询功能.GEO数据结构用于实现附近商户的查询。分页功能完成。思路分析:通过传过来的x,y经纬度,然后我们根据经纬度在redis中查询附近的商户,找到后返回,进行封装,将检测到的结果循环添加到距离中商店位置的,它可以完成?核心源码ShopController@GetMapping("/of/type")publicResultqueryShopByType(@RequestParam("typeId")IntegertypeId,@RequestParam(value="current",defaultValue="1")Integercurrent,@RequestParam(value="x",required=false)Doublex,@RequestParam(value="y",required=false)Doubley){returnshopService.queryShopByType(typeId,current,x,y);}复制代码ShopService@Overridepublic结果queryShopByType(IntegertypeId,Integercurrent,Doublex,Doubley){//1.判断是否需要坐标查询if(x==null||y==null){//不需要坐标查询,通过数据库查询Pagepage=query().eq("type_id",typeId).页面(新页面<>(当前,SystemConstants.DEFAULT_PAGE_SIZE));//返回数据returnResult.ok(page.getRecords());}//2.计算分页参数intform=(current-1)*SystemConstants.DEFAULT_PAGE_SIZE;intend=current*SystemConstants.DEFAULT_PAGE_SIZE;//3.查询redis,按距离排序,分页结果:shopId,distanceStringkey=RedisConstants.SHOP_GEO_KEY+typeId;GeoResults>结果=stringRedisTemplate.opsForGeo().search(key,GeoReference.fromCoordinate(x,y),newDistance(5000),RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs().includeDistance().limit(end));//4.解析idif(results==null){returnResult.ok(Collections.emptyList());}List>>content=results.getContent();//4.1截取from=>endListids=newArrayList<>(content.size());MapdistanceMap=newHashMap<>(content.size());if(content.size()<=form){返回Result.ok(Collections.emptyList());}content.stream().skip(form).forEach(result->{//4.2获取店铺idStringshopIdStr=result.getContent().getName();ids.add(Long.valueOf(shopIdStr));//4.2获取距离Distancedistance=result.getDistance();distanceMap.put(shopIdStr,距离);});//5.按id查询shopStringidStr=StrUtil.join(",",ids);Listshops=query().in("id",ids).last("ORDERBYFIELD(id,"+idStr+")").list();//循环将产品距离放入对象的距离属性中shops.forEach(shop->{shop.setDistance(distanceMap.get(shop.getId().toString()).getValue());});//6.返回结果returnResult.ok(shops);}复制测试代码?附近商户效果图?总结以上就是【Bug终结者】集成Redis实现附近商户功能的微服务SpringBoot简介。附近商户搜索是一个很常见的功能。掌握GEO可以完成类似的需求,高质量的完成开发。快点!努力练习,提高你的技能。科技改变世界!!!