실습의 편의를 위해 일부 코드를 작성해두었다.
@RestController @RequestMapping("/cafe") @RequiredArgsConstructor public class CafeController { private final CafeService cafeService; // Redis에 카페 데이터 추가하는 API @PostMapping public void addCafe(@RequestBody AddCafeRequestDto addCafeRequestDto) { cafeService.addCafe(addCafeRequestDto); } // 특정 위치를 기준으로 지정된 반경 내에 있는 카페를 조회해주는 API @GetMapping("/nearby") public List<Object> findCafesNearby(@RequestParam double longitude, @RequestParam double latitude, @RequestParam double distance) { return cafeService.findCafesNearby(longitude, latitude, distance); } }
@AllArgsConstructor @Getter public class AddCafeRequestDto { private String name; private double longitude; private double latitude; }
@Service @RequiredArgsConstructor public class CafeService { public void addCafe(AddCafeRequestDto addCafeRequestDto) { return; } public List<Object> findCafesNearby(double longitude, double latitude, double distanceKm) { return null; } }
@Service @RequiredArgsConstructor public class CafeService { private final RedisTemplate<String, String> redisTemplate; private static final String GEOSPATIAL_KEY = "cafe"; public void addCafe(AddCafeRequestDto addCafeRequestDto) { // Redis GeoSpatial 자료구조에 카페 데이터 저장 // Redis 명령어에서 'GEOADD [key] [위도] [경도] [member]'와 동일 redisTemplate.opsForGeo() .add(GEOSPATIAL_KEY, new Point(addCafeRequestDto.getLongitude(), addCafeRequestDto.getLatitude()), addCafeRequestDto.getName()); } public List<Object> findCafesNearby(double longitude, double latitude, double distanceKm) { // Redis GeoSpatial 자료구조에서 특정 위치를 기준으로 지정된 반경 내에 있는 카페 조회 (오름차순) // Redis 명령어에서 'GEOSEARCH [key] FROMLONLAT [경도] [위도] BYRADIUS [거리] [단위] ASC WITHDIST'와 동일 GeoSearchCommandArgs args = GeoSearchCommandArgs .newGeoSearchArgs() .includeDistance() .sortAscending(); // ASC WITHDIST return redisTemplate.opsForGeo().search( // GEOSEARCH GEOSPATIAL_KEY, // [key] fromCoordinate(new Point(longitude, latitude)), // FROMLONLAT [경도] 위도] new Distance(distanceKm, Metrics.KILOMETERS), // BYRADIUS [거리] [단위] args // ASC WITHDIST ).getContent().stream() .map(geoResult -> new CafeDistance( geoResult.getContent().getName(), geoResult.getDistance().getValue() // '카페 이름'과 '거리'를 반환 )) .collect(Collectors.toList()); } }