基于SpringBoot+Redis实现查找附近用户的功能

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 使用Redis的GEO命令结合SpringBoot实现查找附近用户的功能,通过`GEOADD`命令添加地理位置信息和`GEORADIUS`命令查询附近用户。

前言

简单记录一下使用Redis的GEO命令,SpringDataRedis提供了十分简单的地理位置定位的功能,实现查找附近用户的功能。

一、Redis的GEO命令之GEOADD、GEORADIUS命令

1.GEOADD 命令

(1)用法:GEOADD key [longitude][ latitude ][member]
(2)作用:用于存储地理位置信息,以便进行地理位置搜索和距离计算等操作。
(3)返回值:成功添加的成员数量。
(4)示例:

redis > GEOADD cities 116.4074 39.9042 Beijing
redis > GEOADD cities NX 121.4737 31.2304 Shanghai

(5)可选参数:
- NX:只在 key 不存在时才执行操作。
- XX:只在 key 存在时才执行操作。
- CH:修改成功的成员数量将被返回

2.GEORADIUS 命令

(1)用法:GEORADIUS key longitude latitude radius
(2)作用:用于查询指定地理位置附近的其他地理位置的命令。
(3)返回值:返回成员列表。
(4)示例:

redis > GEORADIUS User-Location 116.4074 39.9042 100 km

二、示例代码

1.控制层

(1)UserController.java

/**
 * 更新用户位置信息
 * {
 *     "longitude": 113.936099,
 *     "latitude": 22.542364
 * }
 */
@PostMapping("updateUserLocation")
@ResponseBody
@CrossOrigin
public <T> T updateUserLocation(@RequestBody HashMap<String, Object> data) {
   
    return userService.updateUserLocation(data);
}

/**
 * 更新用户位置信息
 * {
 *     "longitude": 113.936099,
 *     "latitude": 22.542364,
 *     "radius": 10
 * }
 */
@PostMapping("nearby")
@ResponseBody
@CrossOrigin
public <T> T nearby(@RequestBody HashMap<String, Object> data) {
   
    return userService.nearby(data);
}

2.接口层

(1)IUserService.java

<T> T updateUserLocation(HashMap<String, Object> data);

<T> T nearby(HashMap<String, Object> data);

3.实现层

(1)UserServiceImpl.java

@Override
public <T> T updateUserLocation(HashMap<String, Object> data) {
   
    HashMap<String, Object> responseObj = new HashMap<>();
    // 获取登录用户
    UserDTO userDTO = RequestHolder.getUser();

    // 获取经纬度
    Double longitude = (Double) data.get("longitude"); // 经度
    Double latitude = (Double) data.get("latitude"); // 维度

    String USER_LOCATION_KEY = "User-Location";
    String phone = userDTO.getPhone();
    stringRedisTemplate.opsForGeo().add(USER_LOCATION_KEY, new Point(longitude, latitude), phone);
    responseObj.put("code", 200);
    responseObj.put("success", true);
    responseObj.put("msg", "更新完成");
    return (T) responseObj;
}

@Override
public <T> T nearby(HashMap<String, Object> data) {
   
    HashMap<String, Object> responseObj = new HashMap<>();
    // 获取登录用户
    UserDTO userDTO = RequestHolder.getUser();

    // 获取经纬度,以及半径
    Double longitude = (Double) data.get("longitude"); // 经度
    Double latitude = (Double) data.get("latitude"); // 维度
    Integer radius = (Integer) data.get("radius"); // 半径

    String USER_LOCATION_KEY = "User-Location";
    String phone = userDTO.getPhone();
    Distance distance = new Distance(radius, Metrics.KILOMETERS); // 距离,单位为千米
    Circle circle = new Circle(new Point(longitude, latitude), distance); // 圆心

    // 使用Redis的地理位置操作对象,在指定范围内查询附近的用户位置信息
    GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = stringRedisTemplate.opsForGeo().radius(USER_LOCATION_KEY, circle);
    List<Object> nearbyUsers = new ArrayList<>();
    for (GeoResult<RedisGeoCommands.GeoLocation<String>> geoResult : geoResults.getContent()) {
   
        Object memberId = geoResult.getContent().getName();
        // 排除查询用户本身
        if (!memberId.equals(phone)) {
   
            nearbyUsers.add(memberId);
        }
    }

    responseObj.put("code", 200);
    responseObj.put("success", true);
    responseObj.put("msg", "更新完成");
    responseObj.put("data", nearbyUsers);
    return (T) responseObj;
}
目录
相关文章
|
1月前
|
NoSQL Java 网络安全
SpringBoot启动时连接Redis报错:ERR This instance has cluster support disabled - 如何解决?
通过以上步骤一般可以解决由于配置不匹配造成的连接错误。在调试问题时,一定要确保服务端和客户端的Redis配置保持同步一致。这能够确保SpringBoot应用顺利连接到正确配置的Redis服务,无论是单机模式还是集群模式。
203 5
|
1月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
361 2
|
2月前
|
NoSQL Java 调度
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
分布式锁是分布式系统中用于同步多节点访问共享资源的机制,防止并发操作带来的冲突。本文介绍了基于Spring Boot和Redis实现分布式锁的技术方案,涵盖锁的获取与释放、Redis配置、服务调度及多实例运行等内容,通过Docker Compose搭建环境,验证了锁的有效性与互斥特性。
211 0
分布式锁与分布式锁使用 Redis 和 Spring Boot 进行调度锁(不带 ShedLock)
|
7月前
|
XML 前端开发 Java
SpringBoot实现文件上传下载功能
本文介绍了如何使用SpringBoot实现文件上传与下载功能,涵盖配置和代码实现。包括Maven依赖配置(如`spring-boot-starter-web`和`spring-boot-starter-thymeleaf`)、前端HTML页面设计、WebConfig路径映射配置、YAML文件路径设置,以及核心的文件上传(通过`MultipartFile`处理)和下载(利用`ResponseEntity`返回文件流)功能的Java代码实现。文章由Colorful_WP撰写,内容详实,适合开发者学习参考。
754 0
|
4月前
|
缓存 前端开发 Java
SpringBoot 实现动态菜单功能完整指南
本文介绍了一个动态菜单系统的实现方案,涵盖数据库设计、SpringBoot后端实现、Vue前端展示及权限控制等内容,适用于中后台系统的权限管理。
437 1
|
3月前
|
存储 NoSQL Redis
采用Redis的Bitmaps实现类似Github连续提交状态的功能。
在现实世界的应用开发中,实现类似于Github提交跟踪系统时,还可能需要考虑用户时区、闰年等日期相关的边界条件,以及辅助数据的存储和查询优化,例如对活跃用户的即时查询和统计等。不过这些都可以在Bitmaps的基础功能之上通过额外的代码逻辑来实现。
108 0
|
6月前
|
消息中间件 缓存 NoSQL
基于Spring Data Redis与RabbitMQ实现字符串缓存和计数功能(数据同步)
总的来说,借助Spring Data Redis和RabbitMQ,我们可以轻松实现字符串缓存和计数的功能。而关键的部分不过是一些"厨房的套路",一旦你掌握了这些套路,那么你就像厨师一样可以准备出一道道饕餮美食了。通过这种方式促进数据处理效率无疑将大大提高我们的生产力。
239 32
|
6月前
|
存储 监控 NoSQL
使用Redis实现延迟消息发送功能
使用 Redis 的密码认证功能,为实例设置密码以防止未授权访问。为消息提供适当加密,确保消息内容在网络传输过程中不被窃取或篡改。
267 16
|
6月前
|
安全 Java API
Spring Boot 功能模块全解析:构建现代Java应用的技术图谱
Spring Boot不是一个单一的工具,而是一个由众多功能模块组成的生态系统。这些模块可以根据应用需求灵活组合,构建从简单的REST API到复杂的微服务系统,再到现代的AI驱动应用。