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

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

基于 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 地理信息 移动应用 实时查询

推荐文章

JavaScript 异步编程入门
2024-11-19 07:07:43 +0800 CST
PHP 如何输出带微秒的时间
2024-11-18 01:58:41 +0800 CST
404错误页面的HTML代码
2024-11-19 06:55:51 +0800 CST
Vue3中如何处理跨域请求?
2024-11-19 08:43:14 +0800 CST
如何开发易支付插件功能
2024-11-19 08:36:25 +0800 CST
MySQL 优化利剑 EXPLAIN
2024-11-19 00:43:21 +0800 CST
Git 常用命令详解
2024-11-18 16:57:24 +0800 CST
详解 Nginx 的 `sub_filter` 指令
2024-11-19 02:09:49 +0800 CST
PostgreSQL日常运维命令总结分享
2024-11-18 06:58:22 +0800 CST
动态渐变背景
2024-11-19 01:49:50 +0800 CST
7种Go语言生成唯一ID的实用方法
2024-11-19 05:22:50 +0800 CST
Go 并发利器 WaitGroup
2024-11-19 02:51:18 +0800 CST
WebSQL数据库:HTML5的非标准伴侣
2024-11-18 22:44:20 +0800 CST
php 连接mssql数据库
2024-11-17 05:01:41 +0800 CST
Vue3的虚拟DOM是如何提高性能的?
2024-11-18 22:12:20 +0800 CST
php常用的正则表达式
2024-11-19 03:48:35 +0800 CST
Go 协程上下文切换的代价
2024-11-19 09:32:28 +0800 CST
Vue 3 中的 Watch 实现及最佳实践
2024-11-18 22:18:40 +0800 CST
如何配置获取微信支付参数
2024-11-19 08:10:41 +0800 CST
程序员茄子在线接单