目录
一、GEO
1、概念
2、相关命令
1.GEOADD
2.GEODIST
3.GEOHASH
4.GEOPOS
5.GEORADIUS
6.GEOSEARCH
7.GEOSEARCHSTORE
二、附近的店铺
1、实现思路
2、代码实现
一、GEO
1、概念
GEO全称Geolocation,Redis种的一种数据结构他代表地理坐标
2、相关命令
1.GEOADD
向redis中添加一个地理空间信息,其中包含经度、维度、值(member)
2.GEODIST
计算两个指定点之间的距离并返回
3.GEOHASH
将指定member的坐标转为hash字符串形式并返回
4.GEOPOS
返回指定member的左边
5.GEORADIUS
指定圆心、半径、找到该圆内包含的所有member,并按照与圆心之间的距离排序后返回。6.2以后已经废弃
6.GEOSEARCH
在指定的范围内搜索member,并按照与指定点之间的距离进行排序后返回,这个范围可以是矩形也可以是圆形
7.GEOSEARCHSTORE
与第六个相同,不过该命令可以将结果存储到一个指定的key中文章来源:https://www.toymoban.com/news/detail-468068.html
二、附近的店铺
1、实现思路
在数据库层面,我们在店铺表上维护两个字段分别是x、y对应经纬度,然后将这些店铺的类型id作为geo数据类型的key将该类型对应的店铺id作为member以及经纬度xy存入member对应的经纬度中,首先我们需要将查出来的店铺信息通过代码(推荐使用Stream流)将相同类型店铺存的id作为key在同一个的map中,然后遍历该集合以类型id作为redis的key的组成,将店铺id与经纬度存入geo中,此时当客户端传来要查询的店铺类型与用户自身的地理位置时,我们只需要通过上述geo数据结构来处理按照距离由近到远的返回店铺id结合,然后查询数据库将该id对应的店铺信息查出后设置他们各自的距离后返回给前端文章来源地址https://www.toymoban.com/news/detail-468068.html
2、代码实现
List<Shop> test(Integer typeId, Integer page, Integer size, Double x, Double y) {
// 参数中 typeId为类型id page当前页数 size每页数据量 x经度 y维度
// 首先判断是否需要根据坐标查询:判断客户端是否传回用户的地理位置
if (x == null || y == null) {
// 不需要按照地理位置查询,则进行正常分页查询
// TODO:调用mapper层查询数据库
return null;
}
// 2.计算分页参数
int from = (page - 1) * size;
int end = page * size;
// 3.查询redis 根据距离排序
String key = "shop:geo:" + typeId;
GeoResults<RedisGeoCommands.GeoLocation<String>> search = stringRedisTemplate.opsForGeo()
.search(
key, // key
GeoReference.fromCoordinate(new Point(x, y)), // 中心点的经纬度
new Distance(5000), // 查询范围单位默认是m
RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs().includeDistance().limit(end) // 将距离返回查询到end
);
if (search == null) return null;
// 4.截取需要的数据
List<GeoResult<RedisGeoCommands.GeoLocation<String>>> content = search.getContent();
if (content.size() < from) {
// 没有下一页了
return null;
}
List<Long> ids = new ArrayList<>(content.size()); // 存储用户id
Map<String,Distance> distanceMap = new HashMap<>(content.size()); // 存储距离
// 截取相应的部分
content.stream().skip(from).forEach(re -> {
// 获取id
String shopIdStr = re.getContent().getName();
ids.add(Long.valueOf(shopIdStr));
// 获取距离
Distance distance = re.getDistance();
distanceMap.put(shopIdStr,distance);
});
// 根据id去查询对应的店铺
List<Shop> dbShops = shopMapper.queryById(ids);
// 将对应的距离赋值给每个shop对象后返回
for (Shop shop:dbShops) {
shop.setDistance(distanceMap.get(shop.getId().toString()).getValue());
}
return dbShops;
}
到了这里,关于【Redis】GEO数据类型之附近的店铺实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!