附近的商店

2023-11-05

看着每天的感染数据在下降,上海解封的日子快到了。打开美团看看附近店铺有没有好吃,准备解封大吃特吃一顿。排序按照距离优先,还有附近几公里之内的店铺。想了解这个功能怎么实现的,查了网上资料,得到的常用的算法是 geohash 和 S2。

Geohash

https://www.jianshu.com/p/2fd0cf12e5ba
https://halfrost.com/go_spatial_search/
https://phrozen.github.io/geohash/

第二个链接比较详细地介绍了 geohash 的原理(学习一下Z 阶曲线),第三个链接用于展示全球的 geohash 编码地图。比如说我在 wtw3x2,该编码是通过规则定义的 base32 转换的,通过反向转换可以得到我的经纬度,而 geohash 就是定义了这个规则,将经纬度的二维数据转换成一维数据,便于存储以及后续的计算。

代码参考链接1

cb58c25ed12fbb1440bda23e6e5d5006.png

在实际应用当中,美食店的位置坐标都会在注册时提供给平台,当我要查找附近的饭店的话,软件获得我的坐标然后在我附近的1.5km附近展示店铺。假设平台有一张表,简单的3个字段(店铺id,店铺的经度,店铺的维度),当用户要查询的时候,用什么方案能快速给用户响应结果呢?

https://www.cnblogs.com/mgbert/p/4146538.html

这篇2014年的文章,介绍了自己使用 mysql 处理上面的问题,sql 很好的使用勾股定理以及对经纬度的数据做双向复合索引,这个方案在2014年4G刚普及那会是没什么问题的。不过放在2022年就不是很适合了,不过好在有其他的比较好的方案,redis 也有 geohash 功能,在速度方面可以比 mysql 方案要好。

geoadd # 增加坐标信息
geodist # 计算两点的距离
geopos # 获取集合中元素的经纬度坐标
geohash  # 获取元素 hash 值
georadiusbymember # 查询指定元素附近的其它元素

2021年美团的活跃商家数量达880万,加上用户的数据可能会有千万或上亿条。如果使用 Redis 的 Geo 数据结构,它们将全部放在一个 zset 集合中。在 Redis 的集群环境中,节点数据的同步以及迁移,当遇到单个 key 的数据过大,会对集群的产生较大的影响,在集群迁移时会出现卡顿现象,影响线上服务的正常运行。所以官方建议 Geo 的数据使用单独的 Redis 实例部署,不使用集群环境。

但是在实际业务环境中,不能单点部署时,就需要对 Geo 数据进行拆分,按国家、省、市等进行拆分。在人口特大城市甚至可以按区(例如:上海浦东浦西鸳鸯锅)拆分,这样就可以显著降低单个 zset 集合的大小。使用redis做缓存查询,数据库做数据持久化,增加定时任务用于redis和数据库的店铺位置信息进行增删改操作,保证一定时间内两边数据一致。

Geohash 利用 Z 阶曲线进行编码,可将二维或者多维空间里的所有点都转换成一维曲线,并且 Z 阶曲线还具有局部保序性。Z 阶曲线通过交织点的坐标值的二进制表示来简单地计算多维度中的点的z值。一旦将数据被加到该排序中,任何一维数据结构,例如二叉搜索树,B树,跳跃表或(具有低有效位被截断)哈希表都可以用来处理数据。通过 Z 阶曲线所得到的顺序可以等同地被描述为从四叉树的深度优先遍历得到的顺序,搜索查找邻近点比较快。可以说基本满足互联网附近的功能业务。

Geohash 有12级,从5000km 到 3.7cm,每一级的变化比较大。Geohash 字符串就比较难选,选择不好每次判断可能就还需要取出周围的8个格子再次进行判断。而 S2 有30级,从 0.7cm² 到 85,000,000km² 。中间每一级的变化都比较平缓,接近于4次方的曲线,所以选择精度不会出现 Geohash 选择困难的问题。

Geohash 需要 12 bytes 存储,而S2 的存储只需要一个 uint64 即可。S2 库里面不仅仅有地理编码,还有其他很多几何计算相关的库。地理编码只是其中的一小部分。S2 还可以解决各种向量计算,面积计算,多边形覆盖,距离问题,球面球体上的问题,解决多边形覆盖的问题。比如给定一个城市,求一个多边形刚刚好覆盖住这个城市。

关于这个算法,个人感觉更偏向于 GIS 方面使用,不管是降维曲线的选择还是其背后的数学原理都是比 geohash 复杂得多。geohash 适合附近的店铺之类的非精确度查询的业务使用,S2 更适合高德地图,优步和 GIS 方面的业务使用。代码方面 C++、java、python 都是实现的,可自行搜索相关资料。

343a29dc7d5d5b03039532a3a10538e7.png

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

附近的商店 的相关文章

  • 保护节点 Redis

    我正在尝试保护 Node Redis IPC 服务器以使用私钥 公钥 我已经关注了本教程 http bencane com 2014 02 18 sending redis traffic through an ssl tunnel wit
  • Redis 块推送直到列表有空位

    我正在寻找类似的东西BLPUSH该命令将阻塞 直到列表的长度低于指定值max size 目的是防止生产者运行速度快于消费者时列表无限增长 功能与 python 非常相似Queue put https docs python org 3 li
  • python 3.5 中的 json.loads 和 Redis

    我使用 json dumps 创建了一个 JSON 对象 并在 Redis 列表中将其 RPUSH ed 当使用 LRANGE redis lrange 返回 JSON 时 我收到一个二进制字符串 b si 00 ff 所以 json lo
  • redis集群不断打印日志WSA_IO_PENDING

    当我启动redis集群的所有redis服务器时 所有这些服务器不断打印类似WSA IO PENDING clusterWriteDone的日志 9956 03 Feb 18 17 25 044 WSA IO PENDING writing
  • 如何在节点redis客户端上设置读取超时?

    在 github 上我没有看到读取超时的选项 https github com NodeRedis node redis https github com NodeRedis node redis There s connect timeo
  • 是否有可嵌入的 Java 替代 Redis?

    根据这个线程 https stackoverflow com questions 3047010 best redis library for java 如果我想从Java中使用Redis Jedis是最好的选择 然而 我想知道是否有任何库
  • Redis INCRBY 有限制

    我想知道是否有一种方法可以通过我的应用程序的单次往返在 Redis 中执行此操作 对于给定的键K 其可能值V是范围内的任意整数 A B 基本上 它有上限和下限 When an INCRBY or DECRBY发出命令 例如INCRBY ke
  • 从redis中检索大数据集

    一台服务器上的应用程序查询另一台服务器上运行的 Redis 查询的结果数据集约为 250kzrangebyscore objects locations inf inf这在应用程序服务器上似乎需要 40 秒 当使用命令执行时redis cl
  • 如何批量删除Redis中数十万个带有特殊字符的key

    我们有一个包含数十万个 Redis 键的列表 其中包含各种特殊字符 我们希望批量删除它们 对于这个问题上的类似问题 有一些很好的答案 如何使用 Redis 自动删除与模式匹配的键 https stackoverflow com questi
  • 在 aws-elasticache 上使用 memcached 或 Redis

    我正在 AWS 上开发一个应用程序 并使用 AWS elasticache 进行缓存 我对使用 memcached 或 redis 感到困惑 我阅读了有关 redis 3 0 2 更新以及它现在如何等同于 memchached 的文章 ht
  • socket.io 广播功能 & Redis pub/sub 架构

    如果有人能帮助我解决一个小疑问 我将不胜感激 使用socket io广播功能和在Redis上使用pub sub设计架构有什么区别 例如 在另一个示例中 node js 服务器正在侦听 socket io 针对 键 模型 todo 和值 数据
  • 为什么 Redis TimeSeries 不捕获聚合中的最后一个元素?

    我试图了解 Redis 的时间序列规则创建的工作原理 但我很困惑为什么 Redis 会忽略聚合中的最后一项 并想知道这是否是预期的行为 我在中创建了示例代码redis cli为了显示 127 0 0 1 6379 gt FLUSHALL O
  • Redis、会话过期和反向查找

    我目前正在构建一个网络应用程序 并想使用 Redis 来存储会话 登录时 会话会使用相应的用户 ID 插入到 Redis 中 并且过期时间设置为 15 分钟 我现在想实现会话的反向查找 获取具有特定用户 ID 的会话 这里的问题是 由于我无
  • 想要在后台不间断地运行redis-server

    我已经下载了 redis 2 6 16 tar gz 文件并安装成功 安装后我运行 src redis server 它工作正常 但我不想每次都手动运行 src redis server 而是希望 redis server 作为后台进程持续
  • Scala 使用的 Redis 客户端库建议

    我正在计划使用 Scala 中的 Redis 实例进行一些工作 并正在寻找有关使用哪些客户端库的建议 理想情况下 如果存在一个好的库 我希望有一个为 Scala 而不是 Java 设计的库 但如果现在这是更好的方法 那么仅使用 Java 客
  • 如何在Redis中只保存一个数据库?

    我是 Redis 新手 有一个与备份相关的问题 目前 我有一个实例在 Windows 服务器上运行 在这个实例中 我当前有一项 工作 将数据存储在一个数据库中 我不想备份这些数据 我必须创造一份新工作 我的第一个想法是将数据存储在另一个数据
  • Spring Redis删除不删除key

    我正在尝试删除一个 Redis 键 但由于某种原因它没有删除 但也没有抛出异常 这是我要删除的代码 import com example service CustomerService import com example model Cu
  • 在 Spring 4 中干掉通用的 RedisTemplate

    我读到你可以拥有 Autowired从 Spring 4 开始泛型 这太棒了 我有一个摘要RedisService我想参加的课程 Autowired一个通用的 RestTemplate 如下所示 public abstract class
  • 当 Jedis 与 Spring Data 一起使用时,为什么数据会以奇怪的键存储在 Redis 中?

    我将 Spring Data Redis 与 Jedis 一起使用 我正在尝试存储带有密钥的哈希值vc list id 我能够成功插入到redis 但是 当我使用 redis cli 检查密钥时 我没有看到密钥vc 501381 相反我看到
  • Spring Redis 排序键

    我在 Redis Spring Data Redis 中有以下键 localhost gt Keys 1 id 1 Name C5796 Site DRG1 2 id 2 Name CX1XE Site DG1 3 id 3 Name C5

随机推荐

  • ARMv7体系结构汇总

    文章目录 1 处理器工作模式 2 处理器工作状态 3 ARM寄存器 3 1 通用寄存器 3 2 状态寄存器 3 3 备份的程序状态寄存器SPSR 3 4 Thumb寄存器 4 ARM指令系统 4 1 指令和指令格式 4 2 指令的可选后缀
  • 科大个人主页/FTP系统

    参考网页 https ustcnet ustc edu cn 2015 0324 c11130a120792 page htm 最终结果如下 大家快来逛逛吧 http home ustc edu cn sa517486
  • linux系统下从/proc中找回误删除的控制文件

    linux系统下从 proc中找回误删除的控制文件 SYS PROD3 gt select name from v controlfile NAME home oracle db1 control01 ctl SYS PROD3 gt rm
  • ZooKeeper 之Apache Curator 客户端使用

    ZooKeeper 原生不足之处 超时重连 不支持自动 需要手动操作 Watch注册一次后会失效 不支持递归创建节点 Apache Curator apache的开源项目 解决watcher注册一次就失效的问题 api更加简单易用 提供更多
  • TCP/IP详解 卷1:协议 学习笔记 第二章 链路层

    链路层主要有三个目的 1 为IP模块发送和接受IP数据报 2 为ARP模块发送ARP请求和接受ARP应答 3 为RARP模块发送RARP请求和接受RARP应答 TCP IP支持不同的链路层协议 这取决于网络所用的硬件 如以太网 令牌环网 F
  • 文字模糊效果(Opencv实现)

    效果图 实现过程 该方法以photoshop中的图层为基本思想 对文字的处理 实际上是将图片作为一幅图像来处理的 而背景是一幅图像 即另一个图层 1 读取文字图片 将图片进行高斯模糊 因高斯模糊是一个卷积的过程 所以可以设定卷积因子的大小
  • qt序列化

    序列化 注意序列的长度
  • STM32MP157 tf-a2.6移植

    STM32MP157 tf a2 6移植 1 初次编译 2 移植 2 1 添加自己的板子 2 2 修改设备树 2 2 1 修改串口Uart 2 2 2 修改时钟 2 2 3 修改电源 2 2 4 修改DDR 2 2 5 修改EMMC 3 编
  • linux:Temporary failure in name resolution&Couldn’t resolve host

    所有域名无法正常解析 ping www baidu com 等域名提示 Temporary failure in name resolution错误 root localhost ping www baidu com ping www ba
  • 开源数据库 H2, HSQLDB, DERBY, PostgreSQL, MySQL区别/对比图表

    开源数据库 H2 HSQLDB DERBY PostgreSQL MySQL区别 对比图表
  • 通过Idea或命令将本地项目上传至git

    通过Idea或命令将本地项目上传至git 一 Git创建仓库 1 登录Gitee账号 点击新建 2 填写如下相关信息 点击创建 3 在此处可以复制项目链接 二 Idea配置和解绑git 提交项目 1 idea打开项目 操作如下 2 在弹框里
  • 关于getComputedStyle的第二个参数的解释

    最近别人问了我一下getComputedStyle的封装过程为什么要写if currentStyle 我当时也没反应过来 毕竟好长时间没有用了 因此决定来探究一下这个getComputedStyle 函数 即是温习也是和大家分享 如果有不对
  • Java Thread类的静态Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler()方法(带示例)...

    线程类静态Thread UncaughtExceptionHandler getDefaultUncaughtExceptionHandler Thread Class static Thread UncaughtExceptionHand
  • 程序“[1344] MyProject2.exe: 本机”已退出,返回值为 0 (0x0) 错误解决方法

    笔记本用的是win7 64位的系统 没法再用以前的VC6 0了 所以就用了VS2010 在编写窗口程序的时候 运行的时候总是一闪而过 并输出以下的信息 还真是麻烦呀 MyProject2 exe 已加载 D vc练习 MyProject2
  • 海湾主机汉字注释表打字出_海湾消防主机字根表-海湾消防主机

    1洁2964金2980 津2982紧2984锦2985仅2986进2988禁2991荆3003 京3009精3011经3013井3014警3015镜3021九3037 酒3038救3040旧3041居3051菊3053局3054巨3062
  • 性能测试之压力测试

    文章目录 一 基本介绍 二 性能指标 三 下载安装JMeter 1 下载安装包 2 启动JMeter 四 使用JMeter 1 模拟用户请求 2 填写测试地址 3 接收测试结果 4 结果解释 一 基本介绍 压力测试考察当前软硬件条件下系统所
  • 学爬虫之前必须先了解的基础

    爬虫的基础 1 先介绍一下啥是爬虫 在这我也就不扯啥嘴皮子了 简单讲 爬虫就是将前端网页上的数据通过一定的方式爬取下来 一般爬虫可以分为 通用爬虫 和 聚焦爬虫 两种 通用爬虫 通用网络爬虫 是 捜索引擎抓取系统 Baidu Google
  • 【Android-JetpackCompose】13、实战在线课程 App

    文章目录 一 BottomNavigation 底部导航 1 1 底部导航栏的布局 点击 1 2 设置 bottomBar 的颜色 1 3 设置顶部 actionBar 的颜色 二 主页 StudyScreen 2 1 顶部状态栏 2 2
  • HTML表格(table)实例

    实例1 课程表 table border 1 width 60 cellpadding 2 caption 课程表 caption tr align center td 时间 日期 td td 一 td tr table
  • 附近的商店

    看着每天的感染数据在下降 上海解封的日子快到了 打开美团看看附近店铺有没有好吃 准备解封大吃特吃一顿 排序按照距离优先 还有附近几公里之内的店铺 想了解这个功能怎么实现的 查了网上资料 得到的常用的算法是 geohash 和 S2 Geoh