需求说明
需求来源于条友的一个项目,根据用户当前所在坐标,查询附近企业,并将距离进行倒排,这是个比价常见的需求,现在将实现过程简单描述一下。
1、原方案
从数据库中加载所有企业的坐标地址,数据量在万级,每个用户查询一次最近的企业,后台计算量就是数万次,N个用户每查询一次,就是N*数万次。
- 优化方案
先从数据库中查询出给定范围的企业,这样计算量就小很多,例如只需要查询1公里范围以内的企业,就不需要数万次那么多了。(当然,如果用户选择的是1万公里以内的企业,还是一个全集,所以这个最大范围需要在C端做限制,比如最大只能查询150公里以内的企业)。
- 方案设计
根据geohash原理,可以理解为将全国地图划分为N个网格,每个网格都有独立的全局12位geohash编码,两个坐标点距离越近,geohash编码的前N位越相似,如图:
Geohash精度说明:
根据上图所示,
如果要查询1公里范围内的,就查询前6位
如果要查询5公里范围内的,就查询前5位
如果要查询40公里范围内的,就查询前4位
如果要查询150公里范围内的,就查询前3位
- 开发步骤
4.1 增加一张企业坐标表
字段名称 | 类型 | 长度 | 备注 |
|
企业id | 同企业表id | 同企业表id长度 |
| 索引 |
经度 | double | 小数点后6位 |
|
|
纬度 | double | 小数点后6位 |
|
|
geohashcode | varchar | 12 | Geohash编码 |
|
km1 | varchar | 6 | 1公里范围 | 加索引 |
km5 | varchar | 5 | 5公里范围 | 加索引 |
km40 | varchar | 4 | 40公里范围 | 加索引 |
km150 | varchar | 3 | 150公里范围 | 加索引 |
4.2 企业坐标数据录入的时候,同时向该表写入坐标相关数据,前三个字段已经有了,geohashcode字段通过Geohash类计算得到,后面四个字段,分别按对应的长度对geohashcode截取:
km1字段,截取geohashcode的前6位得到
km5字段,截取geohashcode的前5位得到
Km40字段,截取geohashcode的前4位得到
Km150字段,截取geohashcode的前3位得到
4.3 用户需要查询企业的时候,如果查询1公里范围内的企业,先将用户坐标转换成geohash编码,再截取用户的geohash编码前6位,拿到这个6位的编码,作为条件去该表查询km1字段值相同的数据,即查询到距离该用户附近1公里的企业列表,拿到该列表再进行之前的排序方案,即可得出距离排序后的企业。