揭秘外卖平台的附近公里设计
背景
相信大家都有点外卖的时候去按照附近公里排序的习惯,那附近的公里是怎么设计的呢?今天shigen
带你一起揭秘。
分析
我们先明确一下需求,每个商家都有一个地址对吧,我们也有一个地址,我们点餐的时候,就是以我们自己所在的位置为圆心,向外辐射,这一圈上有一堆的商家。类似我下方的图展示:
想到了位置,我们自然想到了卫星定位,想到了二维的坐标。那这个需求我们有什么好的设计方案吗?
redis的GEO地理位置坐标这个数据结构刚好能解决我们的需求。
GEO
GEO 是一种地理空间数据结构,它可以存储和处理地理位置信息。它以有序集合(Sorted Set)的形式存储地理位置的经度和纬度,以及与之关联的成员。
以下是 Redis GEO 的一些常见操作:
GEOADD key longitude latitude member [longitude latitude member ...]
:将一个或多个地理位置及其成员添加到指定的键中。 示例:GEOADD cities -122.4194 37.7749 "San Francisco" -74.0059 40.7128 "New York"
GEODIST key member1 member2 [unit]
:计算两个成员之间的距离。 示例:GEODIST cities "San Francisco" "New York" km
GEOPOS key member [member ...]
:获取一个或多个成员的经度和纬度。 示例:GEOPOS cities "San Francisco" "New York"
GEORADIUS key longitude latitude radius unit [WITHCOORD] [WITHDIST] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
:根据给定的经纬度和半径,在指定范围内查找与给定位置相匹配的成员。 示例:GEORADIUS cities -122.4194 37.7749 100 km WITHDIST COUNT 5
Redis 的 GEO 功能可用于许多应用场景,例如:
- 位置服务:可以存储城市、商店、用户等位置信息,并通过距离计算来查找附近的位置。
- 地理围栏:可以存储地理围栏的边界信息,并检查给定的位置是否在围栏内。
- 最短路径:可以将城市或节点作为地理位置,结合图算法,查找两个位置之间的最短路径。
- 热点分析:可以根据位置信息生成热力图,统计热门区域或目标位置的访问频率。
Redis 的 GEO 功能提供了方便且高效的方式来存储和操作地理位置信息,使得处理地理空间数据变得更加简单和快速。
默默的说一句,redis在路径规划下边竟然也这么厉害!
好的,那我们就来开始实现吧。今天我的操作还是用代码来展示,毕竟经纬度在控制台输入可能会出错。
代码实现
今天的案例是将湖北省武汉市各个区的数据存储在redis中,并以我所在的位置计算离别的区距离,以及我最近10km内的区。数据来源
我的测试代码如下,其中的运行结果也在对应的注释上有显示。
因为代码图片的宽度过长,导致代码字体很小,在移动端可尝试横屏观看;在PC端可尝试右键在新标签页打开图片。
以上的代码案例也参考:Redis GEO 常用 RedisTemplate API(Java),感谢作者提供的代码案例支持。
总结
对于需要存储地理数据和需要进行地理计算的需求,可以尝试使用redis进行解决。当然,elasticsearch也提供了对应的数据类型支持。
来源:juejin.cn/post/7275595571733282853