检索技术核心 20 讲
陈东
前数禾科技 CTO,前奇虎 360 商业化资深总监
21492 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 29 讲
检索技术核心 20 讲
15
15
1.0x
00:00/00:00
登录|注册

13 | 空间检索(上):如何用Geohash实现“查找附近的人”功能?

Geohash编码的优点和缺点
地理位置坐标转换为字符串编码
快速寻找邻接区域的编码
建立更大的候选集合
快速查询同个区域的人
区域划分和编号
限定“附近”的范围
查询10公里内的人时的索引技术选择
初期和后期用户量大时的索引技术选择
非精准Top K检索-精准Top K检索的应用案例
利用空间检索技术查找附近的人
Geohash编码
精准查询附近的人
非精准检索思路
课堂讨论
重点回顾
实现“查找附近的人”功能
空间检索

该思维导图由 AI 生成,仅供参考

你好,我是陈东。
现在,越来越多的互联网应用在提供基于地理位置的服务。这些基于地理位置服务,本质上都是检索附近的人或者物的服务。比如说,社交软件可以浏览附近的人,餐饮平台可以查找附近的餐厅,还有出行平台会显示附近的车等。那如果你的老板希望你能为公司的应用开发相关的功能,比如说实现一个“查询附近的人”功能,你会怎么做呢?
一个很容易想到的方案是,把所有人的坐标取出来,计算每个人和自己当前坐标的距离。然后把它们全排序,并且根据距离远近在地图上列出来。但是仔细想想你就会发现,这种方案在大规模的系统中并不可行。
这是因为,如果系统中的人数到达了一定的量级,那计算和所有人的距离再排序,这会是一个非常巨大的代价。尽管,我们可以使用堆排序代替全排序来降低排序代价,但取出所有人的位置信息并计算距离,这本身就是一个很大的开销。
那在大规模系统中实现“查找附近的人功能”,我们有什么更高效的检索方案呢?今天我们就来聊聊这个问题。

使用非精准检索的思路实现“查找附近的人”

事实上,“查找附近的人”和“检索相关的网页”这两个功能的本质是非常相似的。在这两个功能的实现中,我们都没有明确的检索目标,也就都不需要非常精准的检索结果,只需要保证质量足够高的结果包含在 Top K 个结果中就够了。所以,非精准 Top K 检索也可以作为优化方案,来实现“查找附近的人”功能。那具体是如何实现的呢?
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何使用Geohash编码实现“查找附近的人”功能。通过将地球看作二维空间,在水平和垂直方向上进行二分,生成一维的区域编码,再利用一维空间的检索技术对区域编码建立索引。在查询时,可以使用非精准的检索思路直接检索相应的区域编码,实现“查找附近的人”功能。对于精准检索,需要根据检索半径扩大检索范围,一并检索周边的区域,并进行精确的距离计算和排序。文章还介绍了Geohash编码的原理和应用,以及在不同用户量情况下的合理索引技术选择。文章内容深入浅出,为读者提供了实现“查找附近的人”功能的技术思路和方法。 Geohash编码是一种常见的地理位置编码方式,通过将真实世界的地理位置根据经纬度进行区域编码,再使用base32编码生成一维的字符串编码,方便地进行存储和显示。文章还提出了两个课堂讨论问题,引发读者思考和讨论。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《检索技术核心 20 讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(10)

  • 最新
  • 精选
  • 1: 用户量不大的时候:直接可以进行计算具体,这里因为用户的数据是一致在变化的,所以保存的数据结构可以使用 树 和 跳表, 都可以在 log(n) 的时间复杂度中进行查询 用户量很大的时候,可以使用倒排索引, 以区域的 key 建 倒排索引 2: 这里可以利用区域编码的特性,在同一大区域下的小区域的前缀是一样的 这里最小的区域范围为 4.9 km * 4.9 km ,那么可以向上找大一级的区域,此时的区域范围为 9.8 km * 9.8 km 此时还是不满足要查询的范围,所以向上找大一级的区域 此时的区域范围为 18.6 km * 18.6 km 就可以了

    作者回复: 回答得很清晰! 第一个问题,树和跳表都可以,都支持动态修改,并且支持范围查询,可以在log n时间复杂度内完成查询。如果用户量变大,又希望查询效率高。可以用倒排索引。 第二个问题,查询周边两圈就可以了。这样相信你能更好地理解Geohash的原理。当然,还有更多灵活的查询方式,我们下一讲再介绍。

    2020-04-25
    3
    9
  • qinsi
    把地球的球体表面投影到平面的话,相同Geohash编码长度对应的覆盖区域的大小会随着纬度高低变化的吧

    作者回复: 你这个问题很好。的确是这样的,由于地球是球面,直接用经纬度划分格子的话,高纬度地区和低纬度地区的一个格子的范围是不同的。这里其实存在一个误差。因此,真要精准估计区域范围的话,我们应该每隔一个经度或者纬度就累加一个偏差值才对。 不过,在查找附近的人的这类需求上,本来就是非精准检索,因此这个范围表更多是一个参考。帮助我们快速地决定需要使用的Geohash的长度。如果对精度有要求的话,可以按照按文中的思路,扩大范围,减少一个编码长度,取出更大范围的候选集进行精准计算。

    2020-04-24
    6
  • GeoHash两维转一维编码,虽然看上去去是这样,但我老觉得很别扭,我想了想,核心我认为它并没有按照传统的单维度作为一个整体去计算,所以我更认为它是两个作用域无限的维度,转换位2*n个0,1维度表示。

    作者回复: 你的感觉很敏锐。如果结合后面几课一起看的话,你会发现,这其实更像是一个降维映射。而降维以后的每一个bit,都可以看做是向量的一个维度,都有它自己的意义。 最典型的例子,就是我们在计算附近区域的时候,我们其实还是还原回了原始的两个维度,分别处理。然后再合并回来。 因此,从这个角度来说,我们将这两个维度作为两个向量,单独保存,组合检索,其实也是可以的。只是在特定场景下,转为一维编码,再利用大家熟悉的一维空间的检索技术,会更简单,也更容易被大众接受。

    2020-05-16
    2
  • 范闲
    1.小数据量怎么做都可以.大数据量倒排索引+跳表,倒排加速 2.扩大查询范围,可以将GeoHash的编码减少一位。如果一开始是6位,可以变成5位去查。

    作者回复: 回答得很简明扼要。重点把握得不错。

    2020-04-27
    2
  • Bachue Zhou
    其实很多时候还可以根据使用场景对这个编码进行压缩吧,比如大部分情况下,人不会在海上,出现在南北极的概率也很低,出现在其他一些人迹罕至的地方的概率也不高,所以可以根据这一概率对编码进行压缩,得到更精简的编码。

    作者回复: 这是一个很不错的思路,就是根据数据的出现频率来编码压缩。哈夫曼编码就是这样的一种实践。

    2021-01-04
  • 这里 GeoHash 编码字符串的长度和 选定几个比特位作为一个单元和编码方式有关 这里是默认 选5个比特位作为一个单元 和 使用 base32 进行编码吗?

    作者回复: 是的。字符串长度和选择几个比特位作为编码单元是相关的。 一般来说,对于Geohash,我们选择5个比特位作为一个单元,使用base32编码。

    2020-04-25
  • 那时刻
    问题1. 如老师讲过的,在用户量不大的情况下可以采用堆排序对全部用户排序,得到结果。而当用户量增大的时候,需要对二维空间进行编码的方式来解决。区别在于数据量小的情况堆排序可以解决问题,而且不需要额外的空间。当时数据量大的情况,时间复杂度增加,需要来增加空间复杂度,也就是对于空间位置进行二分编码的方式,来降低时间复杂度。 问题2。可以采取您提到精准topk方案,取四个方位的额外4.9km区域,进行综合计算出10km附近的人。

    作者回复: 问题1: 数据量小的时候怎么做都行。如果出于节约空间的角度出发,用数组和链表(跳表)都可以。这样也可以做二分查找,效率也不算差。当数据量大的时候,如果觉得二分查找还不够快,那么还可以建立倒排索引,直接以编码作为key。 问题2:不错,我们是可以扩展周边区域就可以了。不过如果只扩展周围一圈的邻接区域,那么扩展半径只是4.9公里。如果我希望的扩展半径是10公里,你会怎么做呢?

    2020-04-24
  • 老师你好,这个倒排索引的 key 是什么? value 又是什么呢?
    2023-05-20归属地:广东
  • ifelse
    学习打卡
    2023-04-14归属地:浙江
  • 夜空中最亮的星
    干货满满,很受益
    2020-04-24
    1
收起评论
显示
设置
留言
10
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部