![fc3568d7ac40db6451aa81f96e62f982.png](https://i-blog.csdnimg.cn/blog_migrate/87b8270b007d75aa7db7b68f999de693.jpeg)
1
背景:
产品:我需要实现一个功能,根据用户当前定位,推荐周围5公里的入驻的商家
小笨:Bob is your uncle
解释 —— Bob is your uncle(俚语): Bob 是英国保守党党员 罗博.塞西尔的昵称。在他担任首相时,曾经任命他的侄子亚瑟.贝尔福出任爱尔兰的事务大臣。由于贝尔福在当时并没有突出的政治表现,声望也不高,因此人们都认为他是靠关系才能有这样的地位。后来,“鲍勃是你叔叔”,就表示有后台,就没问题。随着发展,现代口语中表示:一切都没问题,放心好了,就这么简单!
思考:
周围5公里:以自己为宇宙的中心,划5公里的半径,皆是自己的天下(2b青年,欢乐多)
经纬度:
- 有效的经度从-180度到180度。
- 有效的纬度从-85.05112878度到85.05112878度。
![b29ea91eff05b08640c5766d2ccdd8e5.png](https://i-blog.csdnimg.cn/blog_migrate/84038ca303890f531d7965596cabf0c4.jpeg)
废话连篇,都是幼本毕业的,接受过高等教育,不需要再赘述了。
实现 :GEO
我们首先需要一个 table,记录这些商家的经纬度,为以后的查询提供数据池。
Redis : GEOADD 时间复杂度为O(log(N))
redis-cli> GEOADD testkey 131.423333 34.3434343 beijing
数据记录之后,在一个数据池里了,为什么就快了呢?因为插入数据之后,内部生成了,
二维 转 一维 的映射。
![26f28a5ebee178b08b74e09765aa4cd9.png](https://i-blog.csdnimg.cn/blog_migrate/086db957c19f9282b4c347d7eec3dcfc.jpeg)
映射
注意观察数据,相近经纬度,生成的 一维字符串也相近,具有公共前缀,引申出
—— GEOHASH
GEOHASH 算法
Geohash 是一种地理编码,由 Gustavo Niemeyer 发明的。它是一种分级的数据结构,把空间划分为网格。Geohash 属于空间填充曲线中的 Z 阶曲线(Z-order curve)的实际应用。
经纬度表格--形似 棋盘。
![98711c1e0a6f0007e78ac8955448d4d9.png](https://i-blog.csdnimg.cn/blog_migrate/a40459e0ca438a197c9503f6e5f35eac.jpeg)
虚拟数据,不可信.gif
本文不深入讲解了,感兴趣的可以:
https://halfrost.com/go_spatial_search
具体使用
1、前边 GEOADD 已经添加数据,现在开始定位用户数据,开始搜索附近
![d42bdaa20c12f29b49646a5b162386c0.png](https://i-blog.csdnimg.cn/blog_migrate/37e1cac58122d7139c0c8b2a2b522e2d.jpeg)
Redis: GEORADIUS
时间复杂度为O(N+log(M)),N为指定半径范围内的元素个数,M为要返回的个数
georadius testkey 130.405285 35.904989 5 km WITHDIST WITHCOORD ASC COUNT 5
- 根据给定的经纬度,返回半径不超过指定距离的元素
- 可以指定WITHDIST返回距离,WITHCOORD返回经纬度,WITHHASH返回geohash值
- 可以指定ASC或DESC,根据距离来排序
- 可以指定COUNT限定返回的记录数
其他
产品:商店因为不景气关门了,不能搜索到
小笨:这个业务合理,无条件支持。
Redis GEO 实际就是 Zset,那么移除就是
zrem testkey beijing
![c8d404e9b30ab2636c6a91adfbd4afa9.png](https://i-blog.csdnimg.cn/blog_migrate/084a3751623b3adb268216a3ef07e03b.jpeg)
左手代码,右手诗,趣味学习新知识