这里假设要实现的是“附近的地铁站”功能,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);