redis GEO数据结构、实现附近商铺功能实践

 更新时间:2025年12月24日 08:49:21   作者:姓蔡小朋友  
文章介绍了Redis中的GEO命令及其用途,包括地理坐标存储、距离计算、坐标转换和位置搜索等功能,还分享了如何使用Redis实现查询附近商铺的功能,包括导入商铺信息和根据类型及距离进行搜索

一、GEO

Grolocation意为地理坐标,允许存储地理坐标信息,完成地理坐标之间距离的计算。

  • geoadd key longitude1 latitude1 field1 longitude2 latitude2 field2...:向图key中添加多个member,包含经度longitude、纬度latitude 、member唯一标识field
  • geodist key field1 field2 [m,km]:返回两个member之间的距离
  • geohash key field1:将指定member的坐标转为hash字符串形式并返回
  • geopos key field1:返回指定member的坐标
  • geoseartch key FROMLONLAT longitude1 latitude1 [BYRADIUS 10km] [ASC/DESC] [WITHDIST]:给定圆心和半径,按照升序或降序返回指定范围内的member,并返回距离具体值WITHDIST
  • geosearchstore:同geoseratch,并将结果存储到指定的key中

GEO底层是用sortedSet实现,其中经纬度会被换算为score字段(score=a+b的意思),member唯一标识作为value字段。

二、redis实现查询附近商铺功能

1.按照商铺类型导入商铺信息

@Resource
StringRedisTemplate stringRedisTemplate;
@Resource
IShopService shopService;
@Test
public void testLoadShopData(){
    List<Shop> shops = shopService.query().list();
    for (Shop shop : shops) {
        stringRedisTemplate.opsForGeo().add(
                "geo:shop:"+shop.getTypeId(),
                new RedisGeoCommands.GeoLocation<>(
                        shop.getId().toString(),
                        new Point(shop.getX().doubleValue(),shop.getY().doubleValue())));
    }

2.根据商铺类型和距离查询附近商铺

@Override
public Result queryShopByType(Integer typeId, Integer current, Double x, Double y) {
    if (x==null || y==null){
        // 根据类型分页查询
        Page<Shop> page = query()
                .eq("type_id", typeId)
                .page(new Page<>(current, 5));
        // 返回数据
        return Result.ok(page.getRecords());
    }
    // 该页起始和终止元素
    int from = (current-1)*5;
    int end = from + 5;
    // 查询距离内的店铺
    GeoResults<RedisGeoCommands.GeoLocation<String>> radius = stringRedisTemplate.opsForGeo().radius(
            "geo:shop:" + typeId,
            new Circle(new Point(x, y), new Distance(5000)),
            RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance());//指定圆心半径m查相关店铺,并返回店铺距离圆心的距离
    // 判空
    if (radius==null){
        return Result.ok(Collections.emptyList());
    }
    // 这里看类的结构只能getContent
    List<GeoResult<RedisGeoCommands.GeoLocation<String>>> results = radius.getContent();

    // 判该页是否有元素
    if (results.size()<=from){
        return Result.ok(Collections.emptyList());
    }

    // 截取from~end部分实现分页
    List<GeoResult<RedisGeoCommands.GeoLocation<String>>> results1 = results.subList(from, Math.min(end, results.size()-1));

    ArrayList<Long> shopIds = new ArrayList<>();
    HashMap<Long, Distance> longDistanceHashMap = new HashMap<>();
    results1.forEach(r ->{
        String shopId = r.getContent().getName();
        shopIds.add(Long.valueOf(shopId));
        Distance distance = r.getDistance();
        longDistanceHashMap.put(Long.valueOf(shopId), distance);
    });

    List<Shop> shops = listByIds(shopIds);
    for (Shop s : shops) {
        double value = longDistanceHashMap.get(s.getId()).getValue();
        s.setDistance(value);
    }

    return Result.ok(shops);
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • php结合redis实现高并发下的抢购、秒杀功能的实例

    php结合redis实现高并发下的抢购、秒杀功能的实例

    下面小编就为大家带来一篇php结合redis实现高并发下的抢购、秒杀功能的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • redis主从复制的原理及实现

    redis主从复制的原理及实现

    Redis主从复制是一种数据同步机制,它通过将一个Redis实例的数据复制到其他Redis,本文主要介绍了redis主从复制的原理及实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • Redis中的通用命令解读

    Redis中的通用命令解读

    这篇文章主要介绍了Redis中的通用命令,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-07-07
  • redis实现分布式全局唯一id的示例代码

    redis实现分布式全局唯一id的示例代码

    在某些场景中,我们需要生成全局的唯一ID,本文主要介绍了redis实现分布式全局唯一id的示例代码,具有一定的参考价值,感兴趣的可以了解一下
    2024-04-04
  • Redis远程字典服务器 hash类型示例详解

    Redis远程字典服务器 hash类型示例详解

    这篇文章主要介绍了Redis远程字典服务器 hash类型示例详解,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-08-08
  • 如何自定义redis工具jar包供其他SpringBoot项目直接使用

    如何自定义redis工具jar包供其他SpringBoot项目直接使用

    这篇文章主要介绍了如何自定义redis工具jar包供其他SpringBoot项目直接使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • Redis 高可用与集群原理深度解析

    Redis 高可用与集群原理深度解析

    Redis高可用机制涵盖主从复制、哨兵自动故障转移及Cluster集群分片与高可用,依赖Gossip协议实现节点通信与状态同步,源码解析了故障转移流程,为后续持久化内容奠定基础,本文给大家介绍Redis高可用与集群原理,感兴趣的朋友跟随小编一起看看吧
    2025-09-09
  • Redis配置文件最佳实践

    Redis配置文件最佳实践

    这篇文章主要介绍了Redis配置文件详解,本文主要是根据Redis6.0.x版本的配置文件讲解,其它版本的也可以当做一个参考,需要的朋友可以参考下
    2025-05-05
  • Windows安装Redis的几种方式与测试流程总结

    Windows安装Redis的几种方式与测试流程总结

    本文系统梳理了在 Windows 系统上安装和使用 Redis 的多种方式,涵盖通过端口号识别运行中的 Redis 实例、进程定位方法,并提供了 Java 环境下的连接与测试示例,同时还介绍了常见的图形化管理工具,便于可视化管理与调试,需要的朋友可以参考下
    2025-05-05
  • 爬虫技术之分布式爬虫架构的讲解

    爬虫技术之分布式爬虫架构的讲解

    今天小编就为大家分享一篇关于爬虫技术之分布式爬虫架构的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01

最新评论