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
命令。例如,查询 member1
和 member2
之间的距离:
$result = $redis->geoDist('KEY', 'member:1', 'member:2', 'km');
geodist
语法说明:
GEODIST key member1 member2 [m|km|ft|mi]
此命令会返回两个位置之间的距离,支持多种单位(米、千米、英里、英尺)。
版权声明:本文为原创文章,版权归 全栈开发技术博客 所有。
本文链接:https://www.lvtao.net/database/php-redis-nearby.html
转载时须注明出处及本声明