Redis的GEO功能在Redis3.2版本提供,支持存储地理位置信息用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能.geo的数据类型为zset。

相关命令:

1.添加经纬度信息(geoadd)

geoadd cityGeo 116.405285 39.904989 "北京"  121.472644 31.231706 "上海"

将给定的空间元素(纬度、经度、名字)添加到指定的键里面

2.查找指定key的经纬度信息(geoadd)

geopos cityGeo 北京

从键里面返回所有给定位置元素的位置(经度和纬度)

3.返回两个地方的距离(geodist)

geodist cityGeo 北京 上海

返回两个地方的距离(默认返回),可以指定单位
m 表示单位为米。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。

4.返回半径不超过指定距离的元素(georadius)

georadius cityGeo 116.405285 39.904989 100 km WITHDIST WITHCOORD ASC COUNT 5

根据给定的经纬度为中心, 返回与中心的距离不超过给定最大距离的所有位置元素。
可以指定WITHDIST返回距离,WITHCOORD返回经纬度,WITHHASH返回geohash值
可以指定ASC或DESC,根据距离来排序
可以指定COUNT限定返回的记录数

5.返回半径不超过指定距离的元素(georadiusbymember)

georadiusbymember cityGeo 北京 100 km WITHDIST WITHCOORD ASC COUNT 5

根据指定的地点查询半径在指定范围内的位置
可以指定WITHDIST返回距离,WITHCOORD返回经纬度,WITHHASH返回geohash值
可以指定ASC或DESC,根据距离来排序
可以指定COUNT限定返回的记录数
这个跟georadiusl类似

6.返回的是geohash值(geohash)

geohash cityGeo 北京

RedisTemplate的GEO使用

public class RedisTemplateTest {

    @Autowired
    private StringRedisTemplate redisTemplate;

    final static String REDIS_KEY = "cityGeoKey";

    /**
     * 添加经纬度信息
     */
    @Test
    public void testGeoAdd(){
        redisTemplate.opsForGeo()
                .add(REDIS_KEY, new Point(116.405285,39.904989),"北京");
        redisTemplate.opsForGeo()
                .add(REDIS_KEY, new Point(121.472644,31.231706),"上海");
    }


    /**
     * 获取经纬度信息
     */
    @Test
    public void testGeoGet(){
        List<Point> position = redisTemplate.opsForGeo()
                .position(REDIS_KEY, "北京", "上海");
        position.forEach(System.err::println);
    }

    /**
     * 两个地点之间的距离
     */
    @Test
    public void testGeoDist(){
       Distance distance =  redisTemplate.opsForGeo()
                .distance(REDIS_KEY, "北京", "上海", RedisGeoCommands.DistanceUnit.KILOMETERS);
        System.err.println(distance);
    }

    /**
     * 根据给定的经纬度,返回半径不超过指定距离的元素
     */
    @Test
    public void testGeoNearByXY(){
        Circle circle = new Circle(116.405285, 39.904989, Metrics.KILOMETERS.getMultiplier());
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands
                .GeoRadiusCommandArgs
                .newGeoRadiusArgs()
                .includeDistance()
                .includeCoordinates()
                .sortAscending()
                .limit(3);
        GeoResults<RedisGeoCommands.GeoLocation<String>> results = redisTemplate.opsForGeo()
                .radius(REDIS_KEY, circle, args);
        System.err.println(results);
    }

    @Test
    public void testGeoNearByPlace(){
        Distance distance = new Distance(2,Metrics.KILOMETERS);
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending().limit(5);
        GeoResults<RedisGeoCommands.GeoLocation<String>>  results = redisTemplate.opsForGeo()
                .radius(REDIS_KEY,"北京",distance,args);
        System.err.println(results);
    }

    /**
     * 获取hash值
     */
    @Test
    public void testGeoHash(){
        List<String> results = redisTemplate.opsForGeo()
                .hash(REDIS_KEY,"北京","上海");
        System.err.println(results);
    }

}