面试问题
Redis 如何实现查询附近的人?
涉及知识点
Redis 中如何操作位置信息?
GEO 底层是如何实现的?
如何在程序实现查询附近的人?
在实际使用中需要注意哪些问题?
视频答案
视频地址: https://www.bilibili.com/video/av89369236/
图文答案
Redis 中要实现查询附近的人, 需要使用 Redis 3.2 版本中提供的 GEO 数据类型, 它包含以下几个重要的方法:
GEOADD 添加元素位置信息;
GEOPOS 查询元素经纬度信息;
GEODIST 查询两个元素的直线距离;
GEORADIUS 查询附近一定距离内的元素信息.
首先我们可以使用百度提供的经纬度查询工具来确定位置信息, 地址: 我们先用百度地图提供的经纬度查询工具, 地址:
命令使用详见视频部分.
代码实战
下面我们用 Java 代码, 来实现查询附近的人, 完整代码如下:
- import Redis.clients.jedis.GeoCoordinate;
- import Redis.clients.jedis.GeoRadiusResponse;
- import Redis.clients.jedis.GeoUnit;
- import Redis.clients.jedis.Jedis;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- public class GeoHashExample {
- public static void main(String[] args) {
- Jedis jedis = new Jedis("127.0.0.1", 6379);
- Map<String, GeoCoordinate> map = new HashMap<>();
- // 添加小明的位置
- map.put("xiaoming", new GeoCoordinate(116.404269, 39.913164));
- // 添加小红的位置
- map.put("xiaohong", new GeoCoordinate(116.36, 39.922461));
- // 添加小美的位置
- map.put("xiaomei", new GeoCoordinate(116.499705, 39.874635));
- // 添加小二
- map.put("xiaoer", new GeoCoordinate(116.193275, 39.996348));
- jedis.geoadd("person", map);
- // 查询小明和小红的直线距离
- System.out.println("小明和小红相距:" + jedis.geodist("person", "xiaoming",
- "xiaohong", GeoUnit.KM) + "KM");
- // 查询小明附近 5 公里的人
- List<GeoRadiusResponse> res = jedis.georadiusByMemberReadonly("person", "xiaoming",
- 5, GeoUnit.KM);
- for (int i = 1; i < res.size(); i++) {
- System.out.println("小明附近的人:" + res.get(i).getMemberByString());
- }
- }
- }
以上程序执行的结果如下:
小明和小红相距: 3.9153 KM
小明附近的人: xiaohong
总结
GEO 是 Redis 3.2 版本中新增的功能, 只有升级到 3.2+ 才能使用, GEO 本质上是基于 ZSet 实现的, 这点在 Redis 源码找到相关信息, 我们可以 GEO 使用实现查找附近的人或者附近的地点, 还可以用它来计算两个位置相隔的直线距离.
来源: https://www.cnblogs.com/vipstone/p/12448355.html