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

前言

简单记录一下使用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 updateUserLocation(@RequestBody HashMap data) {
    return userService.updateUserLocation(data);
}

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

2.接口层

(1)IUserService.java

 T updateUserLocation(HashMap data);

 T nearby(HashMap data);

3.实现层

(1)UserServiceImpl.java

@Override
public  T updateUserLocation(HashMap data) {
    HashMap 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 nearby(HashMap data) {
    HashMap 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> geoResults = stringRedisTemplate.opsForGeo().radius(USER_LOCATION_KEY, circle);
    List nearbyUsers = new ArrayList<>();
    for (GeoResult> 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;
} 
  

你可能感兴趣的:(Java,#,SpringBoot,#,Redis,后端)