目录
一、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.按照商铺类型导入商铺信息:
java
@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.根据商铺类型和距离查询附近商铺:
java
@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);
}