朋友的定位,附近的人,打车距离计算??
Redis的Geo的Redis3.2版本就有了,这个功能可以推算地理位置信息,两地之间的距离,方圆几里的人
可以查询一些测试数据 http://www.jsons.cn/lngcode/
geoadd 添加地理位置
# geoadd 添加地理位置
# 规则:两级无法直接添加,我们一般是下载城市数据,直接通过java程序一次性导入
# 参数 key 值 (经度、纬度、名称)
# 有效的经度 -180到180
# 有效的纬度 -85到85
# 当坐标位置超出上述指定范围时,该命令将会返回一个错误
127.0.0.1:6379> geoadd china:city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqing
(integer) 1
127.0.0.1:6379> geoadd china:city 114.05 22.52 shengzhen
(integer) 1
127.0.0.1:6379> geoadd china:city 120.16 30.24 hangzhou
(integer) 1
127.0.0.1:6379> geoadd china:city 108.96 43.26 xian
(integer) 1
127.0.0.1:6379>
geopos 获取指定城市经度和纬度
获得当前定位:一定是一个坐标值
127.0.0.1:6379> geopos china:city beijing shengzhen hangzhou # 获取指定城市经度和纬度
1) 1) "116.39999896287918091"
2) "39.90000009167092543"
2) 1) "114.04999762773513794"
2) "22.5200000879503861"
3) 1) "120.1600000262260437"
2) "30.2400003229490224"
127.0.0.1:6379>
geodist 返回两个给定位置之间的距离
127.0.0.1:6379> geodist china:city beijing shanghai
"1067378.7564"
127.0.0.1:6379> geodist china:city beijing shanghai km # 指定距离单位
"1067.3788"
127.0.0.1:6379>
georadius 以给定的经纬度为中心,找出某一个半径内的元素
找附近的人? ? (首先要获取所有附近的人的地址,定位)通过半径来查询
127.0.0.1:6379> georadius china:city 110 30 1000 km # 获取 110 30 这个经纬度为中心方圆1000km以内的城市
1) "chongqing"
2) "shengzhen"
3) "hangzhou"
127.0.0.1:6379> georadius china:city 110 30 500 km
1) "chongqing"
# withdist 显示距离
# withcoord 显示经纬度
# count 筛选个数
127.0.0.1:6379> georadius china:city 110 30 1000 km withdist withcoord count 1
1) 1) "chongqing"
2) "341.9374"
3) 1) "106.49999767541885376"
2) "29.52999957900659211"
127.0.0.1:6379>
georadiusbymember 找出指定范围内的元素
与georadius 差不多,只不过是将经纬度换成了具体的城市
# 找出位于指定元素周围的元素
127.0.0.1:6379> georadiusbymember china:city beijing 1000 km
1) "beijing"
2) "xian"
127.0.0.1:6379> georadiusbymember china:city beijing 500 km
1) "beijing"
127.0.0.1:6379>
geohash 返回一个或者多个位置元素的geohash表示
该命令将返回11个字符的Geohash字符串
# 将二维的经纬度转换为一维的字符串,如果两个字符串越接近,那么则距离越近
127.0.0.1:6379> geohash china:city beijing chongqing
1) "wx4fbxxfke0"
2) "wm5xzrybty0"
127.0.0.1:6379>
geo底层的实现原理其实就是Zset,官方文档的命令中没有给出怎么移除一个元素,但我们可以用zset来实现
127.0.0.1:6379> zrange china:city 0 -1 # 查看地图中全部元素
1) "chongqing"
2) "shengzhen"
3) "hangzhou"
4) "shanghai"
5) "beijing"
6) "xian"
127.0.0.1:6379> zrem china:city beijing # 移除指定元素
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "chongqing"
2) "shengzhen"
3) "hangzhou"
4) "shanghai"
5) "xian"
127.0.0.1:6379>
什么是基数?? 一个集合内不重复的数就是基数
redis Hyperloglog 基数统计的算法,
优点:占用的内存是固定的,2的64次方的 不同的元素,只需要费12kb的内存
网页的UV(一个人访问一个网站多次,还是算作一根人)
传统的方式,用set保存用户的id,然后就可以统计set中的元素数据作为标准判断!
这个方式如果保存大量的用户id,就会比较麻烦!但是我们的目的是技术而不是保存用户id
0.81%错误率!
# 测试使用
127.0.0.1:6379> pfadd mykey1 a b c d e f g # 创建第一组元素
(integer) 1
127.0.0.1:6379> pfadd mykey2 x y z b m n # 创建第二组元素
(integer) 1
127.0.0.1:6379> pfcount mykey1 #统计第一组元素基数数量
(integer) 7
127.0.0.1:6379> pfcount mykey2 #统计第二组元素基数数量
(integer) 6
127.0.0.1:6379> pfmerge mykey3 mykey1 mykey2 # pfmerge 合并两组的元素到mykey3
OK
127.0.0.1:6379> pfcount mykey3 #统计第三组元素基数数量(并集去重),不带重复的元素,b是重复的元素
(integer) 12
127.0.0.1:6379>
如果业务允许容错的,那么使用Hyperloglog是首选的
如果业务不允许容错的,那么就是用set或者自己的数据类型即可!
位运算
统计用户信息,活跃,不活跃!登录,未登录,类似两个状态的都可以使用Bitmaps
Bitmaps 位图,数据结构,都是操作二进制位来记录,就只有0和1两个状态
365天=365 bit ,1字节=8位,相当于你只要话46个字节就能表示一个人1年的打卡情况
# 模拟一个人一周的打卡情况
127.0.0.1:6379> setbit issign 0 1
(integer) 0
127.0.0.1:6379> setbit issign 1 1
(integer) 0
127.0.0.1:6379> setbit issign 2 0
(integer) 0
127.0.0.1:6379> setbit issign 3 0
(integer) 0
127.0.0.1:6379> setbit issign 4 1
(integer) 0
127.0.0.1:6379> setbit issign 5 1
(integer) 0
127.0.0.1:6379> setbit issign 6 1
(integer) 0
127.0.0.1:6379>
查看某一天是否打卡?
127.0.0.1:6379> getbit issign 3 # 查看周四的打卡情况
(integer) 0
127.0.0.1:6379> getbit issign 4 # 查看周五的打卡情况
(integer) 1
127.0.0.1:6379>
统计操作,统计打卡的天数
127.0.0.1:6379> bitcount issign # 统计全部打卡的情况
(integer) 5