基于redis的geo类型实现“附近的xx”功能
2023-02-18 16:27:32 时间
这里假设要实现的是“附近的地铁站”功能,key为list,member为地铁站id
首先,你需要在redis里维护一个geo的列表(本质上是sorted set),当每个地铁站的经纬度有更新时,就使用
#地铁站id=1
#顺便提一下,相同key,member,不同经纬度,GEOADD会自动更新的
127.0.0.1:6379> GEOADD list CH 13.361389 38.115556 "1"
列表接口的实现
客户端会传一个经纬度,页码,每页条数,关键词(搜索后排序先不考虑)
生成模拟数据
$redis = new Redis();
$redis->connect("docker-redis", 6379);
$addrs=[
['name'=>'1北京四惠地铁站', 'id'=>1, 'long'=>116.495676, 'lat'=>39.908789],
['name'=>'2北京大望路地铁站', 'id'=>2, 'long'=>116.475835, 'lat'=>39.908278],
['name'=>'3北京国贸地铁站', 'id'=>3, 'long'=>116.459729, 'lat'=>39.908432],
['name'=>'4北京永安里地铁站', 'id'=>4, 'long'=>116.450334, 'lat'=>39.908478],
['name'=>'5北京建国门地铁站', 'id'=>5, 'long'=>116.434768, 'lat'=>39.908587],
['name'=>'6北京东单地铁站', 'id'=>6, 'long'=>116.418504, 'lat'=>39.908366],
['name'=>'7北京王府井地铁站', 'id'=>7, 'long'=>116.411565, 'lat'=>39.908106],
['name'=>'8北京西单地铁站', 'id'=>8, 'long'=>116.376302, 'lat'=>39.907194],
['name'=>'9北京复兴门地铁站', 'id'=>9, 'long'=>116.357757, 'lat'=>39.90715],
['name'=>'10北京南礼士路地铁站', 'id'=>10, 'long'=>116.352589, 'lat'=>39.907247],
['name'=>'11北京木樨地地铁站', 'id'=>11, 'long'=>116.337475, 'lat'=>39.907471],
['name'=>'12北京军事博物馆地铁站', 'id'=>12, 'long'=>116.321411, 'lat'=>39.90744],
];
$args=[];
foreach ($addrs as $v){
$args[]=$v['long'];
$args[]=$v['lat'];
$args[]=$v['id'];
}
$ok=$redis->geoAdd('list',
...$args
);
查询
$r = $redis->geoRadiusByMember('list', 1, 1800, 'km', [
'count' => 100,
// 'store'=>'list2',
'storedist'=>'list3',
'asc',
// 'WITHCOORD',
// 'WITHDIST',
// 'WITHHASH'
]);
$page=$_GET['page'];
$max=$_GET['max'];
$start = ($page-1) * $max;
$r=$redis->zRange('list3', $start, ($start + $max) - 1, true);//分数升序,取全部
var_dump(array_keys($r));
//todo:cw where id in(1,2)
$j=[
['name'=>'1北京四惠地铁站', 'id'=>1, 'long'=>116.495676, 'lat'=>39.908789],
['name'=>'2北京大望路地铁站', 'id'=>2, 'long'=>116.475835, 'lat'=>39.908278],
['name'=>'3北京国贸地铁站', 'id'=>3, 'long'=>116.459729, 'lat'=>39.908432],
];
$arr=[];
foreach ($r as $id=>$v){
foreach ($j as $k=>$item){
if ($item['id']==$id) $j[$k]['dist']=round($v, 2);
}
}
$dist=array_column($j, 'dist');
array_multisort($dist, SORT_DESC, $j);
var_dump($j);
相关文章
- wordpress跨境电商外贸独立站安装WooCommerce插件
- wordpress独立网站域名解析教程
- obs直播录屏软件下载使用教程-制作短视频录制视频教程
- wordpress独立站菜单导航设置教程
- wordpress外贸跨境电商独立站WooCommerce插件安装教程
- wordpress编辑器增加粘贴图片上传服务器教程
- wordpress网站主题安装教程
- 多语言在线客服系统源码-自动识别中英环境-私有化部署完美支持跨境电商网站
- wordpress企业网站搭建教程
- 自动发货发卡系统搭建教程
- 设置display:flex后 flex布局设置单个子元素靠右
- X-Content-Type-Options: nosniff 禁用浏览器类型猜测保证安全性
- 网页在线客服代码-侧边悬浮在线客服/QQ/微信/电话代码
- getUserMedia报错:新版本Chrome中getUserMedia接口在http下不再支持
- elementui的confirm确认框的使用方式
- getUserMedia()出现的常见错误
- php安装向导中判断是否安装的实现思路
- 一款强大的网页在线客服聊天系统:唯一客服搭建教程
- 仿美洽客服系统-gin框架内核独立自主源码开发在线客服系统
- npx是什么