728x90
GEOSEARCH와 GEORADIUS는 둘 다 Valkey의 지리 공간 데이터를 활용하는 명령어지만, 사용 목적과 성능 차이 때문에 선택이 달라집니다.
✅ 1. 명령어 차이
- GEORADIUS: 특정 좌표를 기준으로 반경 내의 위치를 검색합니다.
- GEOSEARCH: 보다 유연한 검색을 제공하며, 기준 좌표나 특정 지점을 중심으로 다양한 형태의 검색이 가능합니다.
✅ 2. 차이점 비교
항목 | GEORADIUS | GEOSEARCH |
기준점 설정 | 좌표 기반 | 좌표 또는 키 기반 |
검색 영역 | 원형 반경 검색 | 원형 또는 사각형 영역 검색 |
정렬 | 거리 기준 정렬 | 거리 기준 정렬 및 필터링 지원 |
반환 데이터 | 위치 이름, 거리 등 선택 가능 | 위치 이름, 거리 등 선택 가능 |
성능 | 단순한 반경 검색에 최적화 | 복잡한 공간 검색에 적합 |
✅ 3. 어떤 상황에서 사용하는가?
- GEORADIUS는 단순히 반경 내의 위치를 빠르게 찾고 싶을 때 사용합니다.
→ 예: 사용자의 현재 위치에서 5km 이내의 편의점을 찾는 경우 - GEOSEARCH는 더 복잡한 조건이나 사각형 영역을 활용해 위치를 검색해야 할 때 유용합니다.
→ 예: 사용자의 이동 경로를 기준으로 경로 주변 일정 거리 내의 관광지를 찾는 경우, ☆가장 가까운 하나만 선택한 경우
✅ 4. 실제 사용 예시
# GEORADIUS 사용 예시
GEORADIUS location 127.0 37.5 5 km WITHDIST
- 위치 기준 반경 5km 이내의 모든 장소 검색
- 거리 정보 포함
# GEOSEARCH 사용 예시
GEOSEARCH location FROMLOC 127.0 37.5 BYBOX 10 10 km ASC
- 기준 위치에서 가로 10km, 세로 10km의 사각형 영역 내의 장소 검색
- 거리 기준으로 오름차순 정렬
✅ 결론
- 단순한 반경 검색이 필요하다면 → GEORADIUS
- 복잡한 영역 검색이나 정렬이 필요하다면 → GEOSEARCH
검색 조건의 복잡성이나 성능 최적화가 필요해서 다른 명령어를 선택.
geoservice.ts
/**
* 반경 5m 이내 북마크 검색 및 상세 정보 반환
* @param latitude 사용자 위도
* @param longitude 사용자 경도
* @returns 반경 내 북마크 상세 정보 목록
*/
async getNearbyBookmarksS(
latitude: number,
longitude: number,
): Promise<any[]> {
console.log('범위탐색');
// 1. GEO에서 반경 5m 내의 북마크 ID 목록 가져오기
const nearbyIds = (await this.client.georadius(
this.S_GEO_KEY,
longitude, // 경도먼저
latitude,
5,
'm',
)) as string[];
console.log('범위탐색 nearbyIds: ', nearbyIds);
// 2. ID 목록을 기반으로 Hash에서 상세 정보 가져오기
const bookmarkDetails = await Promise.all(
nearbyIds.map(async (id) => {
const hashKey = `bookmarkS:${id}`;
const details = await this.client.hgetall(hashKey);
return { id, ...details }; // ID와 상세 정보를 함께 반환
// Hash로 저장된 데이터는 ...details 로 객체의 모든 속성을 전개할 수 있다.
}),
);
console.log('범위탐색 bookmarkDetails: ', bookmarkDetails);
return bookmarkDetails; // 널이 반환됨
}
/**
* 반경 5m 이내 북마크 검색 및 상세 정보 반환
* @param latitude 사용자 위도
* @param longitude 사용자 경도
* @returns 반경 내 북마크 상세 정보 목록
*/
async getNearbyBookmarkP(
latitude: number,
longitude: number,
): Promise<any | null> {
// 1. GEO에서 반경 5m 내의 가장 가까운 북마크 ID 가져오기
const nearestIds = (await this.client.geosearch(
this.P_GEO_KEY,
'FROMLONLAT',
longitude, // 경도먼저
latitude,
'BYRADIUS',
5,
'm',
'ASC', // 가장 가까운 순으로 정렬
'COUNT',
1, // 1개만 가져옴
)) as string[];
if (!nearestIds || nearestIds.length === 0) return null; // 반경 내 북마크가 없으면 null 반환
// 2. 해당 ID의 Hash에서 상세 정보 가져오기
const nearestId = nearestIds[0];
const hashKey = `bookmarkP:${nearestId}`;
const details = await this.client.hgetall(hashKey);
return details && Object.keys(details).length > 0
? { id: nearestId, ...details }
: null;
}
'게임서버-스파르타코딩NodeJs_7기 > CH6 최종 프로젝트' 카테고리의 다른 글
최종 발표 후 부스 지키기 (0) | 2025.03.14 |
---|---|
서브 목록과 유저의 수행목록을 비교하여 해당 업적을 완료하였는지 확인하는 로직 (0) | 2025.03.11 |
트러블슈팅 - 유저위치로 북마커추가 버튼 만들기 (0) | 2025.03.10 |
테스트코드 작성 - achievement관련 (0) | 2025.03.07 |
트렌젝션 적용하는 방법 (0) | 2025.03.05 |