⛄引言
本文参考黑马 点评我的项目
在点评我的项目中 如何 实现 左近商家的查问呢,展现出间隔本人5公里内的商户,这样的性能如何实现?
答案是能够采纳Redis 来实现,当然可能有很多实现形式,本文次要介绍如何应用Redis实现 左近商户的搜寻性能
一、Redis GEO 数据结构用法
⛅GEO根本语法、指令
GEO 就是 GeoLocation 的简写模式,代表地理坐标。Redis在3.2版本中退出了对GEO的反对,容许存储地理坐标信息,帮忙咱们依据经纬度来检索数据。

常见的命令

GEOADD:增加一个天文空间信息,蕴含:经度(longitude)、纬度(latitude)、值(member)
GEODIST:计算指定的两个点之间的间隔并返回
GEOHASH:将指定member的坐标转为hash字符串模式并返回
GEOPOS:返回指定member的坐标
GEORADIUS:指定圆心、半径,找到该圆内蕴含的所有member,并依照与圆心之间的间隔排序后返回。6.当前已废除
GEOSEARCH:在指定范畴内搜寻member,并依照与指定点之间的间隔排序后返回。范畴能够是圆形或矩形。6.2.新性能
GEOSEARCHSTORE:与GEOSEARCH性能统一,不过能够把后果存储到一个指定的key。 6.2.新性能

⚡应用GEO存储经纬度、查问间隔
本篇博文 Redis版本为 6.2版本
进入redis 查问 geo相干指令

应用 GEO 实现以下性能 实现两点之间的间隔查问,以及指定范畴内的地点

需要如下

应用 GEO 增加 北京 (天安门 116.397469 39.908821 、故宫 116.397027 39.918056、北海公园 116.389977 39.933144) 经纬度
查问 天安门 与 故宫之间的间隔
在以上增加的地点中查问 天安门广场 (116.397827 39.90374) 左近2公里的地点

GEOADD 增加

GEOPOS 查看指定地点 经纬度信息

GEOHASH 查看指定地址 经纬度HASH值

拓展: GEOPOS 和 GEOHASH 的区别在于 GEOHASH 节约了 经纬度存储的 内存、缩小不必要的内存耗费,从而晋升性能
GEODIST 查看 天安门 与故宫之间的间隔

GEOSEARCH 查问 天安门广场 左近 2公里的地点

二、SpringBoot 整合Redis 导入 店铺数据 到GEO

编写SpringBoot 单元测试进行导入Redis数据

@Resource
private IShopService shopService;

@Resource
private StringRedisTemplate stringRedisTemplate;

@Test
void loadShopData() {

//1. 查问店铺信息List<Shop> shopList = shopService.list();//2. 把店铺分组,依照typeId分组、typeId统一的放在一个汇合Map<Long, List<Shop>> map = shopList.stream().collect(Collectors.groupingBy(Shop::getTypeId));//3. 分批实现写入redisfor (Map.Entry<Long, List<Shop>> entry : map.entrySet()) {    //3.1 获取类型id    Long typeId = entry.getKey();    String key = RedisConstants.SHOP_GEO_KEY + typeId;    //3.2 获取同类型的店铺的汇合    List<Shop> value = entry.getValue();    List<RedisGeoCommands.GeoLocation<String>> locations = new ArrayList<>(value.size());    //3.3 写入redis GEOADD key 经度 维度 member    for (Shop shop : value) {        locations.add(new RedisGeoCommands.GeoLocation<>(            shop.getId().toString(),            new Point(shop.getX(), shop.getY())));    }    stringRedisTemplate.opsForGeo().add(key, locations);}

}
复制代码
运行结束,查看Redis即可

三、SpringBoot 整合 Redis 实现 左近商户性能
☁️需要介绍
基于黑马点评我的项目实现 左近商户查问性能

采纳GEO 数据结构实现左近商户查问
实现分页性能

思路剖析:
通过传输过去的 x、y 经纬度,而后咱们依据该经纬度去查问redis中左近的商户,查出后即可返回,进行封装,查出来的后果进行循环增加至 Shop 地点间隔,即可实现。
⚡外围源码
ShopController
@GetMapping("/of/type")
public Result queryShopByType(

@RequestParam("typeId") Integer typeId,@RequestParam(value = "current", defaultValue = "1") Integer current,@RequestParam(value = "x", required = false) Double x,@RequestParam(value = "y", required = false) Double y) {return shopService.queryShopByType(typeId, current, x, y);

}
复制代码
ShopService
@Override
public Result queryShopByType(Integer typeId, Integer current, Double x, Double y) {

//1. 判断是否须要坐标查问if (x == null || y == null) {    // 不须要坐标查问,按数据库查问    Page<Shop> page = query()        .eq("type_id", typeId)        .page(new Page<>(current, SystemConstants.DEFAULT_PAGE_SIZE));    // 返回数据    return Result.ok(page.getRecords());}//2. 计算分页参数int form = (current - 1) * SystemConstants.DEFAULT_PAGE_SIZE;int end = current * SystemConstants.DEFAULT_PAGE_SIZE;//3. 查问redis,依照间隔排序、分页 后果:shopId、distanceString key = RedisConstants.SHOP_GEO_KEY + typeId;GeoResults<RedisGeoCommands.GeoLocation<String>> results = stringRedisTemplate.opsForGeo().search(    key,    GeoReference.fromCoordinate(x, y),    new Distance(5000),    RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs().includeDistance().limit(end));//4. 解析idif (results == null) {    return Result.ok(Collections.emptyList());}List<GeoResult<RedisGeoCommands.GeoLocation<String>>> content = results.getContent();//4.1 截取from => endList<Long> ids = new ArrayList<>(content.size());Map<String, Distance> distanceMap = new HashMap<>(content.size());if (content.size() <= form) {    return Result.ok(Collections.emptyList());}content.stream().skip(form).forEach(result -> {    //4.2 获取店铺id    String shopIdStr = result.getContent().getName();    ids.add(Long.valueOf(shopIdStr));    //4.2 获取间隔    Distance distance = result.getDistance();    distanceMap.put(shopIdStr, distance);});//5. 依据id查问shopString idStr = StrUtil.join(",", ids);List<Shop> shops = query().in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list();// 循环将 商品间隔放入对象间隔属性中shops.forEach(shop -> {    shop.setDistance(distanceMap.get(shop.getId().toString()).getValue());});//6. 返回后果return Result.ok(shops);

}
复制代码
进行测试

✅左近商户效果图

⛵小结
以上就是【Bug 终结者】对 微服务 SpringBoot 整合 Redis 实现左近商户性能 的简略介绍,左近商户搜寻,是很常见的性能,把握GEO即可实现该相似的需要,并高质量实现开发,加油! 认真练习,晋升技术。 技术扭转世界!!!