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 {
@Resource
private 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;
}
}