1.bitmaps

1.1 原理

Bitmaps 是在字符串类型上面定义的位操作。一个字节由 8 个二进制位组成。

image.png

1.2 应用场景

  1. 用户访问统计
  2. 在线用户统计

2.Hyperloglogs

Hyperloglogs:提供了一种不太准确的基数统计方法,比如统计网站的 UV,存在一定的误差。


3.GEO

3.1 存储原理

  1. 将三维的地球变成二维的坐标
  2. 将二维的坐标转化成一维的点块
  3. 最后将一维的点块转换为二进制再通过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实操

  1. @RestController
  2. @RequestMapping("geo")
  3. public class GeoController {
  4. @Resource
  5. private RedisTemplate redisTemplate;
  6. public static final String CITY = "city";
  7. /**
  8. * 将指定的地理空间位置(经度,纬度,名称)添加导指定的key中
  9. * @return
  10. */
  11. @GetMapping("geoadd")
  12. public String geoadd() {
  13. Map<String, Point> map = new HashMap<>();
  14. map.put("天安门", new Point(116.403963, 39.915119));
  15. map.put("故宫", new Point(116.403414, 39.924091));
  16. map.put("长城", new Point(116.024067, 40.362639));
  17. redisTemplate.opsForGeo().add(CITY, map);
  18. return map.toString();
  19. }
  20. /**
  21. * 从key里返回所有给定位置元素的位置(经度和纬度)
  22. * @param member
  23. * @return
  24. */
  25. @GetMapping("geopos")
  26. public Point geopos(String member) {
  27. //获取经纬度坐标
  28. List<Point> position = redisTemplate.opsForGeo().position(CITY, member);
  29. return position.get(0);
  30. }
  31. /**
  32. * 返回一个或多个位置元素的geoHash表示
  33. * @param member
  34. * @return
  35. */
  36. @GetMapping("geohash")
  37. public String hash(String member) {
  38. //geohash算法生成32位编码值
  39. List<String> list = redisTemplate.opsForGeo().hash(CITY, member);
  40. return list.get(0);
  41. }
  42. /**
  43. * 返回两个给定位置之间的距离
  44. * @param member1
  45. * @param member2
  46. * @return
  47. */
  48. @GetMapping("geodist")
  49. public Distance distance(String member1, String member2) {
  50. Distance distance = redisTemplate.opsForGeo().distance(CITY, member1, member2, RedisGeoCommands.DistanceUnit.KILOMETERS);
  51. return distance;
  52. }
  53. /**
  54. * 通过 经度纬度查找附近的
  55. *
  56. * @return
  57. */
  58. @GetMapping("georadius")
  59. public GeoResults radiusByxy() {
  60. // 这个坐标是北京王府井位置
  61. Circle circle = new Circle(116.418017, 39.914402, Metrics.MILES.getMultiplier());
  62. //返回50条
  63. RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending().limit(10);
  64. GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisTemplate.opsForGeo().radius(CITY, circle, args);
  65. return geoResults;
  66. }
  67. /**
  68. * 通过地方查找附近
  69. *
  70. * @return
  71. */
  72. @GetMapping("geoadiusbymember")
  73. public GeoResults radiusByMember() {
  74. String member = "天安门";
  75. RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates().sortAscending().limit(10);
  76. // 半径10公里内
  77. Distance distance = new Distance(10, Metrics.KILOMETERS);
  78. GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults = redisTemplate.opsForGeo().radius(CITY, member, distance, args);
  79. return geoResults;
  80. }
  81. }