首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于redis的geo类型实现“附近的xx”功能

基于redis的geo类型实现“附近的xx”功能

作者头像
崔哥
发布2022-12-13 16:15:18
3060
发布2022-12-13 16:15:18
举报
文章被收录于专栏:崔哥的专栏崔哥的专栏

这里假设要实现的是“附近的地铁站”功能,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);
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 列表接口的实现
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档