관리 메뉴

나의 개발일지(김지헌)

항해 99 84일차 12/11일 본문

항해 99

항해 99 84일차 12/11일

코딩이좋아요 2022. 12. 12. 01:13

WIL

가까운 캠핑장 조회 api

현 위치의 좌표를 따서 데이터베이스에 저장되어 있는 캠핑장의 X, Y의 값을 기준으로  30km 내 가까운 캠핑장 리스트 뽑기

1. 모든 캠핑장을 조회하여 x,y 칼럼의 값을 뽑아내서 대조 후 보내주기

2. 모든 캠핑장을 조회하되 가까운 거리의 캠핑장만 뽑아오기

선택지는 두개였고 처음 시도는 1번으로 하였으나 값을 뽑아내기가 힘들고 뽑아낸다 하더라고 로직이 길어 성능이 느릴 거란 판단을 하여서 

2번 방법으로 하기로 하였다.

2번을 선택하고 나서 시퀄라이즈 ORM 또는 mysql 쿼리문으로 작업을 할 것이냐를 두고 고민을 했다.

결론은 mysql 쿼리문 선택 하기로 했고 이유는 시퀄 라이즈 ORM으로는 구현이 힘든 작업이고 검색하고 찾아봐도 원하는 구현 방식을 찾아보기 힘들었다.

그래서 쿼리문으로 작성하기로 했고 진행했다.

  nearCamp: async ({campX,campY}:coordinate) => {
    const query = `SELECT camp.*,
    ( 6371 * acos( cos( radians( $campX ) ) * cos( radians( camp.X) ) * cos( radians( camp.Y ) - 
    radians($campY) ) + sin( radians( $campX) ) * sin( radians( camp.X ) ) ) )as distance
    FROM camp HAVING distance < 30 ORDER BY distance LIMIT 0,2`
    return await sequelize.query(query, {bind:{campX,campY},type: QueryTypes.SELECT})
   },

HAVING distance < 30 ORDER BY distance LIMIT 0,2 지우고 요청하면 캠핑장 거리가 km단위로 찍힌다.

6371은 지구의 지름이고 하버사인 공식을 사용해서 두 지점 간 최단거리를 구하는 공식이다.

as distance FROM camp : distance

HAVING distance < 30  : HAVING 을 사용해서 반경을 제한할 수도 있다.

ORDER BY distance LIMIT 0,2 : 가까운 거리를 기준으로 오름차순 해서 2개의 매장만 가지고 오겠다,

처음에는 SELECT뒤에 바로 (6371...) 이렇게 진행 했었는데 요청을 보내보니 가까운 거리만 계속 나오는 거였다.

코드를 잘 못 쓴 거 같아서 계속 찾아봤는데 이상한 것은 없었고 원하는 값은 나오지 않았다. 그래서 팀원에게 도움을 받아서 코드를 완성했다.

이유는 SELECT 뒤에 camp.* 즉 캠프의 모든 정보를 찾겠다 라는 게 빠져있었고 mysql의 쿼리문에 익숙하지 않아서 못 찾았던 거 같다.

그 후 bind 변수를 사용해서 프런트 앤드에서 들어오는 파라미터를 검증을 하고 바로 데이터베이스에 프런트에서 넘어온 파라미터가 접근하는 일이 없고 인젝션 공격도 방어할 수 있었다.

 

 

'항해 99' 카테고리의 다른 글

항해 99 86일차 12/13일  (0) 2022.12.14
항해 99 85일차 12/12일  (2) 2022.12.13
항해 99 83일차 12/10일  (0) 2022.12.10
항해 99 82일차 12/09일  (0) 2022.12.10
항해 99 81일차 12/08일  (0) 2022.12.09