MongoDB ‘2dsphere’ index를 활용한 Google Map위경도 저장(위치 검색 내역 저장 및 즐겨 찾기 추가) 기능 만들기
어려운 과제였던 것 같았던 위치 검색 기록 저장하기와 Google Map 즐겨 찾는 장소 기록하기 기능 구현하기
개발을 처음 배우거나 배운지 얼마 안 된 사람들이라면 아마 다들 한 번씩은 튜토리얼을 통해 Google API 활용하는 과정을 배웠을 것이다.
API를 따오는 것이 앞으로 개발하는 것에 있을 다양한 API를 사용하는데 구글이나 페이스북 등의 API를 따오는 것이 상대적으로 접근하기가 쉬워서 그런 듯하다.
그런데 그걸 넘어서 API를 좀 더 역동적으로 활용하고 싶은 경우가 종종 있는데,
예를 들면 Google Map에 검색창을 생성해 검색어와 연관된 자동 완성 기능을 함께 사용하거나, 사용자가 검색한 검색 기록을 로그인 했을 때 보여주기, 그리고 자주 찾는 장소 등을 즐겨 찾기로 추가하는 기능 등을 Node.js에서 pug를 사용해 작업해보고자 한다.
그리고 추가적으로 이 기능들을 활용하기 위해 MongoDB에서 제공하는 2dsphere라는 공간 인덱스를 활용하고자 한다.
Node.js 템플릿 엔진에는 대체적으로 pug, ejs, handlebars가 있지만 불필요한 코드량을 줄여주는 점이 개인적으로 마음에 들어 pug를 애용해서 사용하고 있다.
개인적으로 DB 부분은 배우면 배울 수록 최적화에 관한 이슈가 많이 발견되는데, 2dshpere에서 언급되는 “인덱스(index)”도 굉장히 중요한 개념인데, 이 내용들을 정리하는 글이다.
데이터베이스에서 인덱스는 정말 중요한 역할을 하는 것 같다. 인덱스는 요약하면 자주 조회되는 필드를 따로 저장해서 조회 및정렬 시의 속도를 빠르게 하는 기법이다.
사용자로부터 데이터를 조회 받는 명령을 수행하게 될 때, 많은 양의 데이터 (Mongodb에서는 Document를 서칭하는 형태)를 하나 하나 찾게 된다면, 서칭하는데 시간이 많이 소요되니, Document에 index를 걸어 두면 데이터의 설정한 key 값을 가지고 document들을 가리키는 포인터값으로 이뤄진 B-Tree를 생성하게 되는 것 같다.
그 중 index를 구글맵 API를 활용해서 써보기에 좋은 예제가 2dsphere 인데, 위치 정보를 저장하는데 활용하겠다는 뜻이다.
MongoDB에서 위치 정보를 저장하기 위해 2dsphere라는 기능만 제공하는 것은 아니다.
Geospatial Queries라는 영역이 따로 있어서 GeoJSON 데이터를 기반으로해 처리할 수 있는 방법이 다양한 것 같으니, 관련 내용을 찾아서 활용하면 되겠다.
데이터베이스에 위경도 값을 저장하는 방법에 대해서는 위와 같이 설정했다면, Google Map에서 관련 정보를 저장하는 방법은 어떻게 작업할 수 있을까?
내가 처음 Django로 프로그래밍을 접하게 되었을 때, 구글맵에서 다양한 정로를 이끌어 올 수 있게 하는 방법을 고민하는 것은 꽤나 어려운 일이었고, 검색 내역을 저장한다던가, 즐겨찾기 기능을 만드는 것(북마크랑 비슷하게 구현하는 방법일텐데)은 난제였던 것 같다.
그런데 이 방법들에 대해 모듈을 활용해서라도 만드는 방법을 누군가 지도해줄 수 있었다면, 얘기는 많이 달랐을 것 같은데, Node.js에는 다행히도 Google Map 활용에 관한 모듈이 꽤 많이 보급되어 있다 (Npm 모듈에 거의 다 구비되어 있으니)
주목할 코드는 24, 47, 75번째 코드들이다.
24번째 코드는 검색창에 입력한 쿼리를 토대로 유사한 장소를 자동완성시켜주는 결과를 만들어주고,
47번째 코드는 GPS 기반으로 가까운 거리 내에 검색 결과와 유사한 인기 방문 장소를 결과값으로 보여주는 코드다.
그리고 75번째 줄이 즐겨찾기 장소를 추가하는 코드다.
이렇게만 보면 잘 이해가 안될 수 있으니, 구체적으로 풀어서 설명하면, 모든 Google Map 구현의 핵심이 되는 코드는 단 한 줄로 시작되는데,
import googleMaps from “@google/maps”
이다. 이 모듈에서는 구글 API key와 연동하는 별도의 메소드도 갖고 있고, 구글맵을 사용하기 위한 거의 모든 모듈을 갖고 있다고 보면 된다.
각 모듈 별 활용하는 방법은 위의 npm 링크에 있으니 참고하면 될 것 같고, 추가적으로 검색 결과를 저장하는 코드에 대해서 잠깐 언급을 안했으니, 43번째 코드를 확인하면 될 것 같다.
Django를 사용하면서 SQLite를 기본 데이터 베이스로 배우던 시절이 엊그제 같은데, MySQL이나 Mongodb를 사용하면서 학습의 폭이 좀 더 넓어진다는 것을 새삼 느낀다.
무엇보다 MySQL, MongoDB를 Node.js에 연동해 사용하면 (Django도 동일하지만) ORM, ODM을 사용해 프로젝트를 수행하다 보니, 사용하는 언어가 다르더라도 로직이 동일해 진입 장벽을 낮춰주는 것 같다.
검색 기록/즐겨찾기도 잘 생각해보면, 쿼리 검색 내역이 O회 이상 될 경우 즐겨찾기로 저장하거나 그냥 검색창에 입력된 value를 History라는 데이터 베이스로 저장할 수 있게 fetch, axios 등을 써서 보내주면 됐었는데, 내가 웹을 너무 어렵게 생각했었나하는 생각도 든다.
내 인생에서 프로그래밍을 배울 수 있었던 것은 현재형으로 최고의 축복인 것 같다.
또 배우게 되는 새로운 내용들을 틈틈이 기록하자. 내가 이해할 수 있는 말로 풀어서 설명하는 것이 가장 큰 자산이다.
Ryan