文化传媒公司 网站备案,wordpress建站 域名,wordpress主页 摘要,wordpress用户组名称文章目录 前言Geo介绍Geo指令使用使用场景#xff1a;附近的人参考文献 前言
Redis除了常见的五种数据类型之外#xff0c;其实还有一些少见的数据结构#xff0c;如Geo#xff0c;HyperLogLog等。虽然它们少见#xff0c;但是作用却不容小觑。本文将介绍Geo指令的语法和… 文章目录 前言Geo介绍Geo指令使用使用场景附近的人参考文献 前言
Redis除了常见的五种数据类型之外其实还有一些少见的数据结构如GeoHyperLogLog等。虽然它们少见但是作用却不容小觑。本文将介绍Geo指令的语法和使用场景。
Geo介绍
Geo是geolocation的缩写即地理定位器顾名思义就是记录地理位置信息用来进行地址位置排序的数据结构。所以它场景的应用场景便是寻找附近的人最佳路线推荐等等。说到地址位置排序不得不提地理位置距离排序算法GeoHash算法Redis也使用了这个算法。简单来说这个算法就是将某地点的经度和纬度进行编码之后成为的一维整数整数越接近两个地点也就越接近。通过整数可以还原出经纬度坐标整数越长还原出来的坐标损失程度就越小。GeoHash算法会继续对这个整数做一次base32编码使其变成字符串。于是在使用Geo数据结构时可以简单地理解为它只是一个zsetscore是元素地址经过GeoHash算法得到的52位整数在Redis里面经纬度使用52位的整数进行编码value存放该元素。
Geo指令使用 向Geo中添加地理空间信息geoadd key 经度 纬度 具体元素 geoadd restaurant 95 20 沙县小吃
geoadd restaurant 96 19 肯德基 120 27 麦当劳返回指定两个元素的距离geodist key 元素1 元素2 距离单位 geodist restaurant 沙县小吃 肯德基 km获取元素坐标geopos key 元素1 … 元素n geopos restaurant 麦当劳
geopos restaurant 沙县小吃 肯德基获取指定元素坐标的hash字符串geohash key 元素1 geohash restaurant 沙县小吃 获取到的hash值可以到 http://geohash.org/${hash} 上进行定位得到经纬度坐标 指定圆心半径找到该圆范围内的所有元素并按与圆心距离排序后返回georadius key 经度 纬度 半径 单位 withdist/withcoord/withhash count n des/asc georadius restaurant 95 21 100 km withdist count 3 asc # 查找经度95 纬度21的地点半径100公里以内的餐馆正序输出三个餐馆withdist: 同时返回该元素与圆心的距离距离单位为georadius指令指定的单位 withhash: 同时返回52位整数编码后的字符串 withcoord: 同时返回该元素的经纬度坐标
使用场景附近的人 需求实现查看附近的人功能。 实现方案使用geo数据结构将用户的位置经纬度保存在geo中然后对这些信息进行查询。 代码实现代码中saveUserLocation()方法负责添加用户位置信息在添加时使用outOfChina()方法判断做位置检验是否用户位置在国内不在国内就不保存了deleteUserLocation()方法负责删除某用户的位置信息getNearByLocation()方法负责查询某个地方附近的用户。 public class NearbyPeopleDemo {public static void main(String[] args) {Jedis jedis new Jedis(127.0.0.1);jedis.del(LOCATION_KEY);double lon ;double lat ;//向redis中存放用户的地址,随机生成一万个用户。for(int i 0;i10000;i){lon Math.random()*(138-721)72;lat Math.random()*(55-01);//判断该位置是否属于中国不属于就不加了if(!outOfChina(lon,lat)) {saveUserLocation(用户i, lon, lat, jedis);}}System.out.println(添加用户位置信息完毕);System.out.println(距离经度100纬度35位置100km以内的人有哪些getNearByLocation(100, 35, 100, jedis));}private static final String LOCATION_KEY location;/*** 保存用户位置信息* param userId 用户id* param longitude 经度* param latitude 纬度* param jedis*/public static void saveUserLocation(String userId, double longitude, double latitude, Jedis jedis){jedis.geoadd(LOCATION_KEY,longitude,latitude,userId);}/*** 根据用户id删除用户位置信息采用zset的删除方式删除即可* param userId* param jedis*/public static void deleteUserLocation(String userId,Jedis jedis){jedis.zrem(LOCATION_KEY,userId);}/*** 查询附近的人* param longitude 经度* param latitude 纬度* param radius 半径* param jedis* return*/public static ListString getNearByLocation(double longitude, double latitude,double radius,Jedis jedis){ListGeoRadiusResponse georadius jedis.georadius(LOCATION_KEY, longitude, latitude, radius, GeoUnit.KM);return georadius.stream().map(GeoRadiusResponse::getMemberByString).collect(Collectors.toList());}/*** 判断经纬度是否超过了中国* param longitude 经度* param latitude 纬度* return*/public static boolean outOfChina(double longitude,double latitude){if (longitude 72.004 || longitude 137.8347)return true;if (latitude 0.8293 || latitude 55.8271)return true;return false;}}测试结果我们在main方法中随机生成一万个用户位置信息保存在redis中之后调用getNearByLocation()方法查找距离经度100纬度35的位置100km以内的人有哪些运行结果如下
参考文献
《91.Redis深度历险 核心原理与应用实践》–钱文品