springboot使用redis geo获取附近门店
Redis geo 3.2版本以上才有
在进入redis后,使用info命令获取redis版本信息
使用到的命令
-
GEOADD:添加一个地理空间信息,包含:经度(longitude)、纬度(latitude)、值(member) GEODIST:计算指定的两个点之间的距离并返回 GEORADIUS:指定圆心、半径,找到该圆内包含的所有member,并按照与圆心之间的距离排序后返回。(6.x版本废弃,有新的使用方式)
插入两个地理空间位置信息(仅示例,未加小数点存储有误差)
对应的java中使用的redis写法
/** * 放入地理位置 * @param key 主键 * @param locations 位置集合,RedisGeoCommands.GeoLocation<String>型 */ public void setGeoLocation(String key,List<RedisGeoCommands.GeoLocation<String>> locations) { redisTemplate.opsForGeo().add(key,locations); }
list示例
List<RedisGeoCommands.GeoLocation<String>> locations = new ArrayList<>(); locations.add(new RedisGeoCommands.GeoLocation<>("test",new Point(longitude,latitude))); redisUtil.setGeoLocation(key,locations);
查看地理空间位置信息
查看两地距离
查看以first为圆心附近10km内同一key值下位置信息(包含圆心)
public GeoResults<RedisGeoCommands.GeoLocation<String>> getGeoLocation(String key, Circle circle, RedisGeoCommands.GeoRadiusCommandArgs args) { return redisTemplate.opsForGeo().radius(key,circle,args); }
//经纬度信息 Point point = new Point(longitude, latitude); //距离单位 Metric metric = RedisGeoCommands.DistanceUnit.KILOMETERS; //3km以内的 Distance distance = new Distance(3, metric); Circle circle = new Circle(point, distance); // 需要返回5条包括距离的 RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands .GeoRadiusCommandArgs .newGeoRadiusArgs() .includeDistance() .sortAscending() .limit(5); GeoResults<RedisGeoCommands.GeoLocation<String>> results = redisUtil.getGeoLocation(key, circle, args);
去除圆心,并按距离排序,我的解决方案
放在treeSet里,自定义排序,通过set的pollFirst去除第一条数据
TreeSet<MyDistance> set = new TreeSet<>((Comparator.comparingDouble(MyDistance::getDistance))); results.forEach(geoLocationGeoResult -> { set.add(MyDistance); } set.pollFirst();