PHP+Redis查询附近的人功能

在之前的博客《MySQL 查询附近的人》中,使用 MySQL 查询附近的人在用户较少时性能表现尚可。然而,随着应用用户的增多,查询性能问题开始凸显。因此,这篇文章介绍了使用 Redis 的 GEO 数据类型来提升查询效率,特别是在 Redis 6.0 中,这些功能得到了增强,我测试环境使用的是7.2,如果你的版本不支持,请尽可能的使用新版的Redis

Redis 的 GEO 数据类型从 Redis 3.2 版本开始引入,主要用于存储和操作地理位置信息。通过 Redis 的 GEO 功能,可以快速实现类似“查询附近的人”等地理位置相关的功能。

Redis GEO 操作方法

Redis 提供了一系列用于操作地理位置信息的命令,常用的有:

  • geoadd:向指定的 key 添加地理位置的坐标(经度、纬度)。
  • geopos:获取某个地理位置的坐标。
  • geodist:计算两个位置之间的距离。
  • georadius:根据给定的经纬度坐标,获取指定范围内的地理位置集合。
  • georadiusbymember:根据已存储的位置的成员名,获取该地点附近的地理位置集合。
  • geohash:返回位置对象的 geohash 值(用于调试或底层应用)。

开始使用

1. 连接 Redis

首先需要连接到 Redis 服务器。在 Redis 6.0 之后,如果启用了密码或 ACL(访问控制列表),需要通过身份认证登录。

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 如果 Redis 设置了密码或启用了 ACL,可以这样进行认证
// $redis->auth(['user' => 'default', 'pass' => 'password']);

2. 记录用户地理位置信息

我们通过 geoadd 命令来记录用户的位置信息(经度、纬度)。这里用 user:member 作为成员标识。

$redis->geoAdd("KEY", longitude, latitude, "member:1");
$redis->geoAdd("KEY", longitude, latitude, "member:2");

geoadd 语法说明

GEOADD key longitude latitude member [longitude latitude member ...]

该命令将一个或多个地理位置的经纬度和成员名存储到指定的 key 中。

3. 查询附近的人

假设我们想查找某个坐标点附近 10 公里范围内的最多 100 个人,并按距离从近到远排序,可以使用 georadius 命令。

$options = ['WITHDIST', 'COUNT' => 100, 'ASC'];
$lists = $redis->geoRadius('KEY', longitude, latitude, 10, 'km', $options);

georadius 语法说明

GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
  • m:单位为米,默认单位。
  • km:单位为千米。
  • mi:单位为英里。
  • ft:单位为英尺。
  • WITHDIST:返回结果中包含距离信息。
  • WITHCOORD:返回结果中包含经纬度信息。
  • COUNT:限定返回的记录数量。
  • ASC:根据距离从近到远排序。
  • DESC:根据距离从远到近排序。

4. 查询两个用户之间的距离

如果需要查询两个用户(成员)之间的距离,可以使用 geodist 命令。例如,查询 member1member2 之间的距离:

$result = $redis->geoDist('KEY', 'member:1', 'member:2', 'km');

geodist 语法说明

GEODIST key member1 member2 [m|km|ft|mi]

此命令会返回两个位置之间的距离,支持多种单位(米、千米、英里、英尺)。

标签: PHP, Redis

相关文章

Typecho博客系统的xmlrpc的使用附PHP示例代码

XML-RPC 是一种远程过程调用(RPC)协议,它使用 XML 编码请求和响应,并通过 HTTP 进行传输。XML-RPC 允许客户端调用远程服务器上的方法,并获取返回结果。这种协议简单、轻量...

php+mysql中如何处理嵌套(子)事务并保持原子性一致

在PHP和MySQL中处理子事务并保持原子性一致性是一个复杂但非常重要的问题,尤其是在处理涉及多个数据库操作的业务逻辑时。以下是一些关键的解决方案、思路、技术要点和涉及的难点讲解。解决方案与思路...

如何使用Go编写跨平台组件并让Java或PHP调用

在现代软件开发中,跨语言调用是一个常见的需求。假设我们有一个用Go语言编写的组件,我们希望Java或PHP能够直接调用这个组件中对外提供的方法。为了实现这一目标,我们可以使用以下几种方法:1. ...

深入解析PHP的filter_var函数及其应用场景

在PHP开发中,数据的过滤与验证是至关重要的环节。PHP的 filter_var 函数提供了一种简洁而强大的方式来对输入数据进行验证和过滤。本篇文章将从专业的角度详细介绍 filter_var ...

Typecho开发数据库常用API操作

表创建和删除在 Typecho 插件开发过程中,往往需要创建表。可以使用query()来进行表的创建、修改或者删除。$db= Typecho_Db::get(); $prefix = $db-&...

PHP开启 OPCache 来降低负载并提高抗并发能力

opcache 其实就是 OpCode + cache,php 是一种解释型语言,它的执行可分为以下几个流程这样一来的话,对于同一个文件,反复请求,就要不断解析、编译和执行PHP脚本,消耗过多资...

Typecho博客模板制作手册

文件结构说明文件名作用必须style.css主题样式文件否screenshot.png主题缩略图,图片后缀支持 jpg,png,gif,bmp,jpeg否index.php首页以及说明文件是40...

图片Base64编码

CSR生成

图片无损放大

图片占位符

Excel拆分文件