马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
Geospatial
焦点操作- // 添加店铺数据预热操作,GEOADD key 经度 纬度 member
- stringRedisTemplate.opsForGeo().add(key, new Point(shop.getX(), shop.getY()), shop.getId().toString());
-
- // 具体查询,GEOSEARCH key BYLONLAT x y BYRADIUS 10 WITHDISTANCE
- GeoResults<RedisGeoCommands.GeoLocation<String>> results = stringRedisTemplate.opsForGeo()
- .search(
- key,
- GeoReference.fromCoordinate(x, y),// 圆心
- new Distance(5000),//距离圆心的距离
- RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs().includeDistance().limit(end) //
- );
复制代码 做数据预热:将商户信息添加到Redis里才华查到附件商户信息,每个商户包罗店肆id、经纬度 x , y。由于前端是按类型查询一群店肆信息的,所以要将同一类型的商户添加到同一个组里。- void loadShopData() {
- // 1.查询店铺信息
- List<Shop> list = shopService.list();
- // 2.把店铺分组,按照typeId分组,typeId一致的放到一个集合
- Map<Long, List<Shop>> map = list.stream().collect(Collectors.groupingBy(Shop::getTypeId));
- // 3.分批完成写入Redis
- for (Map.Entry<Long, List<Shop>> entry : map.entrySet()) {
- // 3.1.获取类型id
- Long typeId = entry.getKey();
- String key = SHOP_GEO_KEY + typeId;
- // 3.2.获取同类型的店铺的集合
- List<Shop> value = entry.getValue();
- List<RedisGeoCommands.GeoLocation<String>> locations = new ArrayList<>(value.size());
- // 3.3.写入redis GEOADD key 经度 纬度 member
- for (Shop shop : value) {
- // stringRedisTemplate.opsForGeo().add(key, new Point(shop.getX(), shop.getY()), shop.getId().toString());
- locations.add(new RedisGeoCommands.GeoLocation<>(
- shop.getId().toString(),
- new Point(shop.getX(), shop.getY())
- ));
- }
- stringRedisTemplate.opsForGeo().add(key, locations);
- }
- }
复制代码 依靠- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>
- spring-boot-starter-data-redis
- </artifactId>
- <exclusions>
- <exclusion>
- <artifactId>spring-data-redis</artifactId>
- <groupId>org.springframework.data</groupId>
- </exclusion>
- <exclusion>
- <artifactId>lettuce-core</artifactId>
- <groupId>io.lettuce</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.springframework.data</groupId>
- <artifactId>spring-data-redis</artifactId>
- <version>2.6.2</version>
- </dependency>
- <dependency>
- <groupId>io.lettuce</groupId>
- <artifactId>lettuce-core</artifactId>
- <version>6.1.6.RELEASE</version>
- </dependency>
复制代码 ShopController- @GetMapping("/of/type")
- public Result queryShopByType(
- @RequestParam("typeId") Integer typeId,
- @RequestParam(value = "current", defaultValue = "1") Integer current,
- @RequestParam(value = "x", required = false) Double x,
- @RequestParam(value = "y", required = false) Double y
- ) {
- return shopService.queryShopByType(typeId, current, x, y);
- }
复制代码 ShopServiceImpl- @Override
- public Result queryShopByType(Integer typeId, Integer current, Double x, Double y) {
- // 1.判断是否需要根据坐标查询
- if (x == null || y == null) {
- // 不需要坐标查询,按数据库查询
- Page<Shop> page = query()
- .eq("type_id", typeId)
- .page(new Page<>(current, SystemConstants.DEFAULT_PAGE_SIZE));
- // 返回数据
- return Result.ok(page.getRecords());
- }
-
- // 2.计算分页参数
- int from = (current - 1) * SystemConstants.DEFAULT_PAGE_SIZE;
- int end = current * SystemConstants.DEFAULT_PAGE_SIZE;
-
- // 3.查询redis、按照距离排序、分页。结果:shopId、distance
- String key = SHOP_GEO_KEY + typeId;
- GeoResults<RedisGeoCommands.GeoLocation<String>> results = stringRedisTemplate.opsForGeo() // GEOSEARCH key BYLONLAT x y BYRADIUS 10 WITHDISTANCE
- .search(
- key,
- GeoReference.fromCoordinate(x, y),
- new Distance(5000),
- RedisGeoCommands.GeoSearchCommandArgs.newGeoSearchArgs().includeDistance().limit(end) //这里是从第一条到结束,所以要截取需要的数据返回
- );
- // 4.解析出id
- if (results == null) {
- return Result.ok(Collections.emptyList());
- }
- List<GeoResult<RedisGeoCommands.GeoLocation<String>>> list = results.getContent();
- if (list.size() <= from) {
- // 没有下一页了,结束
- return Result.ok(Collections.emptyList());
- }
- // 4.1.截取 from ~ end的部分
- List<Long> ids = new ArrayList<>(list.size());
- Map<String, Distance> distanceMap = new HashMap<>(list.size());
-
- list.stream().skip(from).forEach(result -> {
- // 4.2.获取店铺id
- String shopIdStr = result.getContent().getName();
- ids.add(Long.valueOf(shopIdStr));
- // 4.3.获取距离
- Distance distance = result.getDistance();
- distanceMap.put(shopIdStr, distance);
- });
- // 5.根据id查询Shop
- String idStr = StrUtil.join(",", ids);
- List<Shop> shops = query().in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list();
- for (Shop shop : shops) {
- shop.setDistance(distanceMap.get(shop.getId().toString()).getValue());
- }
- // 6.返回
- return Result.ok(shops);
- }
复制代码 |