1.bitmaps
1.1 原理
Bitmaps 是在字符串类型上面定义的位操作。一个字节由 8 个二进制位组成。
1.2 应用场景
- 用户访问统计
- 在线用户统计
2.Hyperloglogs
Hyperloglogs:提供了一种不太准确的基数统计方法,比如统计网站的 UV,存在一定的误差。
3.GEO
3.1 存储原理
- 将三维的地球变成二维的坐标
- 将二维的坐标转化成一维的点块
- 最后将一维的点块转换为二进制再通过base32编码
3.2 命令
| redis命令 | 描述 |
|---|---|
| GEOHASH | 返回一个或多个位置元素的geoHash表示 |
| GEOPOS | 从key里返回所有给定位置元素的位置(经度和纬度) |
| GEODIST | 返回两个给定位置之间的距离 |
| GEORADIUS | 以给定的经纬度为中心,找出某一半径内的元素 |
| GEOADD | 将指定的地理空间位置(经度,纬度,名称)添加导指定的key中 |
| GEORADIUSBYMEMBER | 找出位于指定范围内的元素,中心点是由给定的位置元素决定 |
GEORADIUS
GEORADIUS 116.418017 39.914402 10 km withdist withcoord count 10 withhash desc
WITHDIST:在返回位置元素的同时,将位置元素与中心之间的距离也一并返回。距离的单位和用户给定的范围单位保持一致。
WITHCOORD:将位置元素的经度和纬度也一并返回。
WITHHASH:以52位有符号整数的形式,返回位置元素经过原始geohash编码的有序集合分值。这个选项主要用于底层应用或者调试,实际的作用并不大。解决redis客户端中文乱码:
redis -cli --raw
3.3实操
@RestController@RequestMapping("geo")public class GeoController {@Resourceprivate RedisTemplate redisTemplate;public static final String CITY = "city";/*** 将指定的地理空间位置(经度,纬度,名称)添加导指定的key中* @return*/@GetMapping("geoadd")public String geoadd() {Map<String, Point> map = new HashMap<>();map.put("天安门", new Point(116.403963, 39.915119));map.put("故宫", new Point(116.403414, 39.924091));map.put("长城", new Point(116.024067, 40.362639));redisTemplate.opsForGeo().add(CITY, map);return map.toString();}/*** 从key里返回所有给定位置元素的位置(经度和纬度)* @param member* @return*/@GetMapping("geopos")public Point geopos(String member) {//获取经纬度坐标List<Point> position = redisTemplate.opsForGeo().position(CITY, member);return position.get(0);}/*** 返回一个或多个位置元素的geoHash表示* @param member* @return*/@GetMapping("geohash")public String hash(String member) {//geohash算法生成32位编码值List<String> list = redisTemplate.opsForGeo().hash(CITY, member);return list.get(0);}/*** 返回两个给定位置之间的距离* @param member1* @param member2* @return*/@GetMapping("geodist")public Distance distance(String member1, String member2) {Distance distance = redisTemplate.opsForGeo().distance(CITY, member1, member2, RedisGeoCommands.DistanceUnit.KILOMETERS);return distance;}/*** 通过 经度纬度查找附近的** @return*/@GetMapping("georadius")public GeoResults radiusByxy() {// 这个坐标是北京王府井位置Circle circle = new Circle(116.418017, 39.914402, Metrics.MILES.getMultiplier());//返回50条RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending().limit(10);GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisTemplate.opsForGeo().radius(CITY, circle, args);return geoResults;}/*** 通过地方查找附近** @return*/@GetMapping("geoadiusbymember")public GeoResults radiusByMember() {String member = "天安门";RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending().limit(10);// 半径10公里内Distance distance = new Distance(10, Metrics.KILOMETERS);GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisTemplate.opsForGeo().radius(CITY, member, distance, args);return geoResults;}}
