MongoDB 적용하기 - 주문수 체크하기

유수민·2022년 9월 2일
0

모먹지 프로젝트

목록 보기
4/4
post-thumbnail

이제 내가 직접 MongoDB를 이용해 실습하는 시간을 가졌다. 지금 이 글을 적고 있는 현재는 실습을 다 끝낸 후에 해당하여 실습하기 전 MongoDB를 대하는 자세가 확연히 달라졌음을 느낀다. MongoDB 입문편을 통해, MongoDB에 대한 저항감이 줄어들었다고 생각했는데 아니었다. 내가 할 수 있을지에 대한 의구심도 존재했다. 그래서 은근히 미루고 있는 나를 마주보면서 이젠 진짜 해야한다는 생각에 프로젝트를 키고 구글링을 하며 적용하였다. 다 끝난 지금 보니, "별거 아니네? 도대체 왜 이걸 두려워했던거지"라는 의문점이 들 정도라 시작 전의 내가 가소롭기 그지 없다ㅎㅎ. 계속해서 새로운 경험을 하게 될 나에게 이 기록을 통해 두려워하지 말고 막상 해보면 별거아니라고 말해주고 싶었다.
저항감 요소 중 하나는 적용하는 방법을 찾기가 쉽지 않았다는 점이었다. 나는 MongoDB 관련 이슈를 프로젝트에 적용하기 위한 과정 중 프로젝트 자체에서 MongoRepository에서 어노테이션을 이용해 직접 쿼리를 날려야 하는 경우도 있었는데, 많은 블로그들이 MongoDB를 어떻게 설치하고 "터미널창"에서 MongoDB쿼리문을 어떻게 날리는지에 대해서만 작성하고 있었다. 따라서 막상 프로젝트를 적용하기 위해 구글링을 했을 때는 내용들에 비해 많은 도움이 안되었고, 시간이 많이 소요되었었다. 혹시 다른 분들도 이런 상황에서 어려움이 있을까봐 이슈를 해결한 과정을 곁들어서 간단히 글로 남겨두려고 한다.

📌이슈는?

MongoDB는 이전에 작성한 개념 정리 글에서 언급했던 것과 같이, 쌓아 놓고 삭제가 없는 경우가 제일 적합하기 때문에 통계 수집과 지표를 위한 로그 데이터에 많이 사용하는 데이터베이스이다. 따라서 나는 MongoDB를 이용한 것 중 하나가 가게의 주문수를 아는 것이라 생각했고 이를 적용해보고자 한다.
간단하게 틀만 잡는다면 현재 MongoDB가 프로젝트에 이미 구축해놓은 상태로, 모든 API가 호출 될 때마다 로그가 쌓여지도록 되어있다. 해당 로그 데이터를 활용하여 주문 수를 셀 수 있도록 하고 싶었다.

📌첫번째


위의 사진에 있는 것처럼 로그 데이터 중 내가 활용할 수 있는 필드는 어떤 API를 호출하였는지 알 수 있는 uri 필드와 해당 API가 성공적으로 응답되었다는 것을 알 수 있는 status 필드였다. 즉, url가 "/api/order"에 해당하면서 응답이 성공한, status가 "200"인 것을 로그 데이터 중 추출하여만 했다.

📖MongoRepository 파악

MySql과 같은 RDB가 Spring Boot에서 JpaRepository를 이용해서 데이터 검색을 쉽게 할 수 있는 것처럼 MongoDB에서도 MongoRepository를 이용해서 데이터를 쉽게 검색할 수 있게 되어 있다. MongoRepository 인터페이스에 대해 작성한 스프링 공식 문서와 spring-quickly라는 책을 통해 MongoRepository가 상속받은 인터페이스가 JpaRepository와 비슷함을 알 수 있다.

uri와 status의 조건에 해당하는 데이터의 수를 세는 것이기 때문에 count를 쓰기로 결정했다.

📖적용 결과

적용해본 결과, 제대로 작동하였다.

  • 코드

  • postman 결과

📚설계 다시하기

postman에서 결과가 제대로 나오는 순간 너무 행복했다. 근데 어? 이것은 가게 상관없이 전체 총 주문 수가 아닌가?? 내가 의도했던 것은 가게마다의 주문수였다. 그렇다 처음에 잘못 설계했던 것이다. 즉, storeId라는 조건이 더 필요했다. 그런데 쌓여진 로그데이터에서 이를 나타낸 데이터가 없는데?

원래는 parameters의 값을 활용해야 했지만 그 값이 넣어지고 있지 않다는 것을 확인하여 로그 데이터를 쌓게 하는 이슈를 해결하였던 진홍님과 상의를 하게 되었다. 잘못된 상황이 파악되었다. 결론적으로 로그데이터에서 parameters 필드를 requestBody와 requestParams 필드로 새로 바꾸고 값이 잘 들어가주록 하는 새로운 이슈가 생성되었고, 나는 이와 더불어 한가지 더 요청을 하였다.
예를 들어 order api를 호출할 경우의 requestBody에

빨간 묶음의 데이터들이 들어가게 될것인데 이를 활용할 수 있도록 key, value 형태로 들어가게 해달라는 요청이었다.즉, String 형태로 인식하게될 데이터를 json형태로 변환하여 key, value 형태로 만들어달라고 하였다.생각보다 까다로웠을 텐데 잘 해결해주신 진홍님께 감사의 인사를 전한다. 덕분에 나는 제대로 된 데이터를 받을 수 있게 되었다.

  • 바뀌어진 형태

📌두번째

이전까지는 uri와 status 필드가 "/api/order"이고 "200" 인 것만 찾아서 수를 세면 되었었는데 한가지 조건이 더 추가 되었다. 즉, 추가로requestBody 필드에 있는 storeId의 값이 부합되는 것을 찾아야 한다. 나는 기존에 단순히 쿼리문을 던져주는 방식이 아닌 어노테이션을 통해 직접 쿼리를 던져줘야한다고 생각했다.

mysql로 쿼리를 직접 던져주는 것은 해봤어도 MongoDB로 쿼리를 직접 던져주는 것은 해보지 않았고 분명히 문법이 다를텐데 이에 대해 설명하는 곳이 별로 없어 은근히 애를 먹었다. 결국 계속된 구글링을 통해 @Query를 통해 쿼리 날리는 방법을 찾았다!!

📚파라미터 넣어주기

출처 : https://www.baeldung.com/queries-in-spring-data-mongodb

📚requestbody의 storeId 값의 파라미터 넣어주기

출처 : https://stackoverflow.com/questions/36793641/mongodb-query-with-spring-data-for-key-value
예시에서는 attributes 필드의 age값

📚count 하기

출처 : https://www.baeldung.com/spring-data-mongodb-count

📖적용 결과

결과적으로 성공했다! 완전 뿌듯했다.

  • 코드

  • PostMan 결과

📌피드백

  1. LogRepository 속 메소드 이름 바꾸기
    countOrderNumber -> countOrders
  2. 고정된 값인 uri와 status 매개변수화 된것 빼주기.

📌의문점

구글링하면서 들게 된 의문점을 적어보고자 한다.
현재 MongoDB를 통해 주문수를 세는 것을 기존의 모든 API 호출을 기록한 로그 데이터 중 일련의 조건에 부합하는 주문에 해당하는 것만 세는 로직으로 구성해놓았다. 구글링을 하다보니 내가 이용한 방식인 기존의 로그데이터 중 필요한 데이터만 추출하는 형식이 아닌, 따로 원하는 조건에 해당하는 로그데이터를 먼저 쌓아놓고 해당 로그데이터가 총 몇개인지 세는 로직으로 구성하기도 했다. 즉, 정리하자면

  • 기존에 모든 API 호출에 대해 기록하는 로그데이터를 활용하여 여기서 원하는 데이터 추출
    VS
  • 원하는 호출일때 로그데이터를 따로 쌓게 만들어 해당 로그데이터를 활용

으로 두가지 설계 방법이 있었다.

여기서 내가 든 의문점은
1. 최종적으로 수를 세는데 있어서 속도 또는 성능의 차이가 있을까?
(아마 주문수 세기 이슈에서는 "전체 로그 데이터에서 조건에 맞는 주문 로그 데이터 세기 vs 쌓아놓은 주문 로그 데이터 중 해당 가게에 해당하는 주문 로그 데이터 세기" 인데 속도나 성능적인 차이가 있을까?).

2. 조건에 맞는 로그데이터를 먼저 쌓는다고 한들 다시 추출해야 하는 경우도 많아서 후자의 방법은 잘 사용 안하지 않을까?

3. 현직에서는 어떤 방법을 이용을 할까?
로 3가지의 의문점이 들어 멘토님께 질문을 했다.

📖멘토님의 답변

멘토님의 답변을 통해 얻은 결론은 두가지 방법 중 무엇을 쓰느냐는 "선택의 이슈" 일 뿐라는 것이다. 실무에서는 READ에 맞춰서 데이터를 쌓는 방식을 이용한다.

정리하자면,

  • 기존에 모든 API 호출에 대해 기록하는 로그데이터를 활용하여 여기서 원하는 데이터 추출하는 방법
    -장점 : MongoDB의 장점인 유연한 검색을 잘 활용한 방법이다.
    -단점 : RDBMS랑 동일하게, NoSQL (&MongoDB)도 같은 콜렉션 에 데이터가 많을 수록 느려진다.
  • 원하는 호출일때 로그데이터를 따로 쌓게 만들어 해당 로그데이터를 활용하는 방법
    -장점 : 쌓인 데이터가 적어 빠르다.
    -단점 : MongoDB의 장점인 유연한 검색을 배제하는 것이다. 다른 검색 조건을 추가하면 유연하지 못하다.
    -🌟어떠한 데이터를 검색 조건에 맞게, 저장 최적화를 해두는 것으로 캐싱의 일종인 방식
    -🌟조건에 맞게 쌓는 용도로는 Redis같은 Key-Value 기반의 디비가 좀 더 빠르기 때문에 다른 DB를 써서 최적화하는게 낫긴 하지만 선택의 문제이다.
profile
배우는 것이 즐겁다!

0개의 댓글