Redis中地理位置GEO模块,非常便捷的来查找附近的人或物

     从Redis3.2 版本以后,增加了地理位置 GEO 模块,这个模块提供了6个Geo指令,分别是geoadd、geodist、geopos、geohash、georadiusbymember及georadius,通过这个模块的这些命令,可以用来实现平时开发需求当中的“附近的什么什么”,例如即时通讯中附近的人、外卖中附近的餐馆、共享单车中附近的车等等。

Redis中地理位置GEO模块,非常便捷的来查找附近的人或物_第1张图片

地图元素的位置数据使用经纬度表示,经纬度是经度与纬度的合称组成一个坐标系统,称为地理坐标系统,它是一种利用三度空间的球面来定义地球上的空间的球面坐标系统,能够标示地球上的任何一个位置。经度范围 (-180, 180],纬度范围 (-90, 90],纬度正负以赤道为界,北正南负,也是称为北纬和南纬,经度正负以本初子午线 (英国格林尼治天文台) 为界,东正西负,也是称为东经和西经。

Redis中地理位置GEO模块,非常便捷的来查找附近的人或物_第2张图片

Redis中地理位置GEO模块,非常便捷的来查找附近的人或物_第3张图片

无论人或者物,我们存储这一个地理位置点的时候,会存储元素 id,、经度 x,、纬度 y,当我们用关系型数据库存储时,计算两点之间的距离时可以满足需求的,如果要是给定一点,算出该点附近的点,那么我们不可能通过遍历来计算所有的元素和目标元素的距离然后再进行排序,这个计算量太大了,性能指标肯定无法满足。临时的解决方法就是通过矩形区域来限定元素的数量,然后对区域内的元素进行全量距离计算再排序,这样可以明显减少计算量。但是数据库查询性能毕竟有限,如果附近的功能查询请求非常多,在高并发场合,这可能并不是一个很好的方案。

Redis中地理位置GEO模块,非常便捷的来查找附近的人或物_第4张图片

市场的需求,就是程序员努力提升自我能力的方向。IT界的解决方案,通常是层出不穷并且包罗万象,对于地理位置距离排序,通常用的算法是 GeoHash 算法,Redis 也使用 GeoHash 算法。GeoHash 算法将二维的经纬度数据映射到一维的整数,这样所有的元素都将在挂载到一条线上,距离靠近的二维坐标映射到一维后的点之间距离也会很接近。当我们想要计算“附近的什么”时,首先将目标位置映射到这条线上,然后在这个一维的线上获取附近的点就行了。先来讲一讲Redis 的 Geo 指令基本使用:

1、geoadd:
语法:geoadd key longitude latitude member [longitude latitude member……]
功能:将给定的空间元素(维度、经度、名字)添加到指定的键里面
2、geopos
语法:geopos key member [member……]
功能:从键里面返回所有给定位置元素的位置(经度和维度)
3、geodist
语法:geodist key member1 member2 [unit]
功能:返回两个给定位置之间的距离
4、georadius
语法:georadius key longitude latitude radius m|km|gt|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]
功能:以给定的经纬度为中心,返回键包含的位置元素当中,与中心的距离不超过给定最大距离的而所有位置元素。
选项:
WITHDIST:在返回位置元素的同时,将位置元素与中心之间的距离也一并返回。
WITHCOORD:将位置元素的经度和纬度也一并返回。
WITHHASH:以52位有符号整数的形式,返回位置元素经过原始geohash编码的有序集合分值。这个选项主要用于底层应用或者调试,实际中的作用并不大。
ASC:根据中心的位置,按照从近到远的方式返回位置元素
DESC:根据中心的位置,按照从远到近的方式返回位置元素
5、georadiusbymember
语法:georadiusbymemeber key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]
功能:这个命令和georadius命令一样,不同的是中心点是由给定的位置元素决定的
6、geohash
语法:geohash key member [member……]
功能:返回一个或多个位置元素的geohash表示

下面我们来实际操作一下,比如查询附近的公司,先来添加一些公司,可以使用百度的坐标拾取器来获取坐标点:

Redis中地理位置GEO模块,非常便捷的来查找附近的人或物_第5张图片

Redis中地理位置GEO模块,非常便捷的来查找附近的人或物_第6张图片

geodist 指令可以用来计算两个元素之间的距离,参数传集合名称、2 个名称和距离单位。

Redis中地理位置GEO模块,非常便捷的来查找附近的人或物_第7张图片

geopos 指令可以获取集合中任意元素的经纬度坐标,可以一次获取多个。

Redis中地理位置GEO模块,非常便捷的来查找附近的人或物_第8张图片

geohash 可以获取元素的经纬度编码字符串,上面已经提到,它是 base32 编码。 你可以使用这个编码值去 http://geohash.org/${hash} 中进行直接定位,它是 geohash 的标准编码值。

Redis中地理位置GEO模块,非常便捷的来查找附近的人或物_第9张图片

Redis中地理位置GEO模块,非常便捷的来查找附近的人或物_第10张图片

georadiusbymember 指令是最为关键的指令,它可以用来查询指定元素附近的其它元素,按照我们上面说的语法可以来查询附近的元素:

Redis中地理位置GEO模块,非常便捷的来查找附近的人或物_第11张图片

看来阿里离腾讯有些远呀!

除了 georadiusbymember 指令根据元素查询附近的元素,Redis 还提供了根据坐标值来查询附近的元素,这个指令更加有用,它可以根据用户的定位来计算“附近的什么”,这个指令就是georadius:

Redis中地理位置GEO模块,非常便捷的来查找附近的人或物_第12张图片

到此为止,我们介绍了Redis的GEO地理模块,也介绍了模块中的指令及使用,是不是可以满足需求中要开发“附近的什么”的功能了?

 

你可能感兴趣的:(nosql,缓存,数据库)