编程 php基于 Redis 实现的附近车辆查询功能

2024-11-18 21:06:44 +0800 CST views 749

基于 Redis 实现的附近车辆查询功能

前言

随着移动互联网的快速发展,移动互联网已覆盖我们生活的方方面面!
日常生活中,我们所使用的外卖、打车、附近商家等功能是如何实现的呢?

比如:

  • 外卖:如何根据用户的当前位置找到附近的商家?
  • 打车:当用户需要打车时,系统如何安排距离较近的车辆?
  • 社交:微信“附近的人”、陌陌、探探等交友功能是如何实现的?

了解这些功能的实现原理后,我们可以通过 Redis 的 geo 特性轻松实现类似功能!


Redis 的 Geo 特性简介

通过 Redis 的 geo 特性,我们可以存储用户上报的经纬度信息,并基于这些信息进行距离计算等操作。
Redis 3.2 版本引入了 geo 特性,因此要使用该功能,需要将 Redis 版本升级至 3.2 及以上。


实现步骤

第一步:用户坐标信息上报

在移动端获取 GPS 权限后,设备定时向服务器上报当前的经纬度信息。
例如:滴滴打车的车辆会定时上报当前车辆的经纬度信息。
服务器通过 Redis 的 geo 特性将这些坐标信息存储在 Redis 中。

命令参考

  • GEOADD key longitude latitude member
    将某一地点(经纬度坐标)存入 Redis。

示例代码

<?php
$redis = new \Redis();
$redis->connect('redis', 6379);

// 向 "carlist" 集合中增加两个车辆(car1、car2)的经纬度坐标
$redis->geoadd('carlist', '-100.6331263694', '40.2054986348', 'car1');
$redis->geoadd('carlist', '-100.6306533726', '40.2047529787', 'car2');

执行结果:将两个车辆的坐标成功存储到 Redis 中。


第二步:根据用户当前坐标查询附近车辆

当用户请求打车时,系统会接收到用户的当前坐标。
系统将根据该坐标,在指定范围内(如 5 公里)查找距离用户较近的车辆。

命令参考

  • GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]
    根据指定的经纬度坐标,查询指定半径范围内的所有元素。

示例代码

<?php
$redis = new \Redis();
$redis->connect('redis', 6379);

// 查询距离用户坐标(-100.6301598462, 40.2067989295)5 公里范围内的车辆
// 返回结果包含车辆的距离和坐标,并按距离由近及远排序
$carlist = $redis->georadius('carlist', '-100.6301598462', '40.2067989295', 5, 'km', ['WITHDIST', 'WITHCOORD', 'ASC']);
var_dump($carlist);

执行结果

array(2) {
  [0]=>
  array(3) {
    [0]=>
    string(4) "car2"
    [1]=>
    string(6) "0.2315"  // 距离(公里)
    [2]=>
    array(2) {
      [0]=>
      string(22) "-100.63065379858016968"  // 车辆的经度
      [1]=>
      string(20) "40.20475215137940239"    // 车辆的纬度
    }
  }
  [1]=>
  array(3) {
    [0]=>
    string(4) "car1"
    [1]=>
    string(6) "0.2905"  // 距离(公里)
    [2]=>
    array(2) {
      [0]=>
      string(22) "-100.63312679529190063"  // 车辆的经度
      [1]=>
      string(20) "40.20549989412140945"    // 车辆的纬度
    }
  }
}

附言

在实际项目中,用户或车辆的位置可以通过长连接协议(如 WebSocket)实时上报到服务器。
基于 GEORADIUS 的灵活参数,我们可以按需返回距离、坐标信息以及排序等。

虽然 MySQL 相关函数也可以实现类似功能,但在处理实时地理信息时不推荐使用 MySQL。
MongoDB 和 Elasticsearch 也提供了强大的地理位置查询功能,具体实现可以参考相关文档。


Redis Geo 其他命令

更多 Redis Geo 命令及用法请参考官方文档:Geo 命令文档

复制全文 生成海报 Redis 地理信息 移动应用 实时查询

推荐文章

imap_open绕过exec禁用的脚本
2024-11-17 05:01:58 +0800 CST
PHP 的生成器,用过的都说好!
2024-11-18 04:43:02 +0800 CST
gin整合go-assets进行打包模版文件
2024-11-18 09:48:51 +0800 CST
Elasticsearch 监控和警报
2024-11-19 10:02:29 +0800 CST
防止 macOS 生成 .DS_Store 文件
2024-11-19 07:39:27 +0800 CST
Node.js中接入微信支付
2024-11-19 06:28:31 +0800 CST
Claude:审美炸裂的网页生成工具
2024-11-19 09:38:41 +0800 CST
FastAPI 入门指南
2024-11-19 08:51:54 +0800 CST
Python设计模式之工厂模式详解
2024-11-19 09:36:23 +0800 CST
vue打包后如何进行调试错误
2024-11-17 18:20:37 +0800 CST
Vue 中如何处理父子组件通信?
2024-11-17 04:35:13 +0800 CST
PHP 压缩包脚本功能说明
2024-11-19 03:35:29 +0800 CST
Elasticsearch 聚合和分析
2024-11-19 06:44:08 +0800 CST
FcDesigner:低代码表单设计平台
2024-11-19 03:50:18 +0800 CST
最全面的 `history` 命令指南
2024-11-18 21:32:45 +0800 CST
Golang在整洁架构中优雅使用事务
2024-11-18 19:26:04 +0800 CST
Vue3中的Store模式有哪些改进?
2024-11-18 11:47:53 +0800 CST
Vue中如何处理异步更新DOM?
2024-11-18 22:38:53 +0800 CST
windows下mysql使用source导入数据
2024-11-17 05:03:50 +0800 CST
程序员茄子在线接单