一、geo
grolocation意为地理坐标,允许存储地理坐标信息,完成地理坐标之间距离的计算。
geoadd key longitude1 latitude1 field1 longitude2 latitude2 field2...:向图key中添加多个member,包含经度longitude、纬度latitude 、member唯一标识fieldgeodist key field1 field2 [m,km]:返回两个member之间的距离geohash key field1:将指定member的坐标转为hash字符串形式并返回geopos key field1:返回指定member的坐标geoseartch key fromlonlat longitude1 latitude1 [byradius 10km] [asc/desc] [withdist]:给定圆心和半径,按照升序或降序返回指定范围内的member,并返回距离具体值withdistgeosearchstore:同geoseratch,并将结果存储到指定的key中
geo底层是用sortedset实现,其中经纬度会被换算为score字段(score=a+b的意思),member唯一标识作为value字段。

二、redis实现查询附近商铺功能
1.按照商铺类型导入商铺信息
@resource
stringredistemplate stringredistemplate;
@resource
ishopservice shopservice;
@test
public void testloadshopdata(){
list<shop> shops = shopservice.query().list();
for (shop shop : shops) {
stringredistemplate.opsforgeo().add(
"geo:shop:"+shop.gettypeid(),
new redisgeocommands.geolocation<>(
shop.getid().tostring(),
new point(shop.getx().doublevalue(),shop.gety().doublevalue())));
}
2.根据商铺类型和距离查询附近商铺
@override
public result queryshopbytype(integer typeid, integer current, double x, double y) {
if (x==null || y==null){
// 根据类型分页查询
page<shop> page = query()
.eq("type_id", typeid)
.page(new page<>(current, 5));
// 返回数据
return result.ok(page.getrecords());
}
// 该页起始和终止元素
int from = (current-1)*5;
int end = from + 5;
// 查询距离内的店铺
georesults<redisgeocommands.geolocation<string>> radius = stringredistemplate.opsforgeo().radius(
"geo:shop:" + typeid,
new circle(new point(x, y), new distance(5000)),
redisgeocommands.georadiuscommandargs.newgeoradiusargs().includedistance());//指定圆心半径m查相关店铺,并返回店铺距离圆心的距离
// 判空
if (radius==null){
return result.ok(collections.emptylist());
}
// 这里看类的结构只能getcontent
list<georesult<redisgeocommands.geolocation<string>>> results = radius.getcontent();
// 判该页是否有元素
if (results.size()<=from){
return result.ok(collections.emptylist());
}
// 截取from~end部分实现分页
list<georesult<redisgeocommands.geolocation<string>>> results1 = results.sublist(from, math.min(end, results.size()-1));
arraylist<long> shopids = new arraylist<>();
hashmap<long, distance> longdistancehashmap = new hashmap<>();
results1.foreach(r ->{
string shopid = r.getcontent().getname();
shopids.add(long.valueof(shopid));
distance distance = r.getdistance();
longdistancehashmap.put(long.valueof(shopid), distance);
});
list<shop> shops = listbyids(shopids);
for (shop s : shops) {
double value = longdistancehashmap.get(s.getid()).getvalue();
s.setdistance(value);
}
return result.ok(shops);
}
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论