문제 및 해결

Prisma&MongoDB 랜덤 레코드 받아오기

2023. 7. 25. 18:22

풀스택 프로젝트 개발을 위해 Prisma ORM과 Database로 MongoDB를 채택하여 사용했다.

Book 모델에서 랜덤한 데이터를 받아오기 위해 조사를 하였다.

 

21년 2월 prisma 깃헙 질문으로 올라온 글을 살펴보았다. (링크) 해당 글에선 다양한 답변이 있었기에 몇 개 살펴보자. 

const productsCount = await prisma.product.count();
const skip = Math.floor(Math.random() * productsCount);
return await prisma.product.findMany({
    take: 5,
    skip: skip,
    orderBy: {
        sellingCount: 'desc',
    },
});

skip을 이용해서 데이터들을 랜덤으로 스킵하면서 5개의 데이터를 받는 코드이다. 이 코드의 문제는 스킵이 마지막에 다다르면 예상치 않게 5개의 데이터를 받아오지 못할 것이다. 이것을 보완한 코드가 있었지만 이 또한 성능면에서 좋지 않다. 

 

또 다른 대안은, 원시 쿼리를 이용하는 것이다. 

results = await prisma.$queryRawUnsafe(
    // DO NOT pass in or accept user input here
    `SELECT * FROM "Post" ORDER BY RANDOM() LIMIT 30;`,
)

하지만 이 코드는 MongoDB를 데이터베이스로 한다면 동작하지 않으며 원시 쿼리를 이용하는 것은 피하는 것이 좋다고 한다. 그래서 prisma 공식 문서를 뒤져 MongoDB에 관한 내용을 찾아보았다. (링크) MongoDB 버전 3.9.0 이상의 경우 Prisma Client는 원시 쿼리를 보낼 수 있는 세 가지 방법을 제공한다!! 그중 aggregateRaw는  MongoDB에서 제공하는 $sample(링크)을 사용할 수 있다. $sample은 선택할 수를 지정하면 해당하는 수(size)만큼 랜덤으로 record를 반환해 준다! 이걸 활용하면 되겠다 싶었다!

 

const books = await prisma.book.aggregateRaw({
      pipeline: [
        { $match: { genreId: params.genreId } },
        { $sample: { size: 1 } },
      ],
    });

$sample만 이용하면 문제없이 들어오는 것을 확인했지만 특정 장르에 해당하는 book 데이터를 받아오려니 빈 배열만 반환했다.. 에러도 없으니 뭐가 문제인가 싶었다. match문에 문제가 있다는 것을 인지했고, 확인해 본 걸과 Book은 genreId를 단순한 문자열 형태의 id를 들고 있는 것이 아닌 ObejectId("") 형태의 데이터를 들고 있었다는 점이다! (Genre와 Book 테이블은 일대다로 연결되어 있기 때문)

 

    const books = await prisma.book.aggregateRaw({
      pipeline: [
        { $match: { genreId: { $oid: params.genreId } } },
        { $sample: { size: 1 } },
      ],
    });

드디어!! 특정 장르의 책 데이터를 랜덤으로 받아오는 api를 만들 수 있었다! 

랜덤으로 데이터를 받아오는 것은 프로젝트 시작 전부터 조사했던 문제였기에 많은 시간을 쏟긴 했지만 막상 부딪혀보니 생각보다 쉽게(?) 풀린 것 같다. 처음 사용해 보는 prisma, mongoDB지만 나름대로 잘 해결해나가고 있는 것 같다.

 

저작자표시 비영리 동일조건 (새창열림)

'문제 및 해결' 카테고리의 다른 글

Prisma를 활용한 트랜잭션 처리: 두 테이블 동시 업데이트  (0) 2023.07.31
Intersection Observer API를 이용한 무한 스크롤 구현  (0) 2023.05.16
[React]텍스트 슬라이더 구현하기(No Lib)  (0) 2023.01.26
Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the life..  (0) 2022.10.14
webpack 사용 시 비디오 출력  (0) 2022.09.08
'문제 및 해결' 카테고리의 다른 글
  • Prisma를 활용한 트랜잭션 처리: 두 테이블 동시 업데이트
  • Intersection Observer API를 이용한 무한 스크롤 구현
  • [React]텍스트 슬라이더 구현하기(No Lib)
  • Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the life..
JMins
JMins
안녕하세요. 프론트엔드 개발자 김정민입니다. 개발 지식을 공유하고 기록하는 공간입니다.
JMins
개발자 노트
JMins
전체
오늘
어제
  • 분류 전체보기 (85)
    • 개발자의 공부 (73)
      • React (17)
      • 자료구조&알고리즘 (28)
      • JS (17)
      • TS (8)
      • Nodejs (0)
      • Nextjs (1)
      • 기타 (1)
      • Design Pattenrs (0)
      • 테스트 및 최적화 (1)
    • 문제 및 해결 (9)
    • 기본 지식 (3)
    • 챌린지 (0)

블로그 메뉴

  • 홈

공지사항

  • #블로그 스킨 변경
  • 개인적으로 공부를 기록하기 위해 적고 있습니다.

인기 글

최근 댓글

최근 글

hELLO · Designed By 정상우.
JMins
Prisma&MongoDB 랜덤 레코드 받아오기
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.