내일배움캠프 TIL (221215): MongoDB로 게시글, 댓글 CRUD API 만들기

Jiumn·2022년 12월 16일
0
post-thumbnail

오늘 한 일

  • 노드 입문 주차 개인 과제

<노드 입문 주차 개인 과제 내용>
1. 전체 게시글 목록 조회 API
- 제목, 작성자명, 작성 날짜를 조회하기
- 작성 날짜 기준으로 내림차순 정렬하기
2. 게시글 작성 API
- 제목, 작성자명, 비밀번호, 작성 내용을 입력하기
3. 게시글 조회 API
- 제목, 작성자명, 작성 날짜, 작성 내용을 조회하기
(검색 기능이 아닙니다. 간단한 게시글 조회만 구현해주세요.)
4. 게시글 수정 API
- API를 호출할 때 입력된 비밀번호를 비교하여 동일할 때만 글이 수정되게 하기
5. 게시글 삭제 API
- API를 호출할 때 입력된 비밀번호를 비교하여 동일할 때만 글이 삭제되게 하기
6. 댓글 목록 조회
- 조회하는 게시글에 작성된 모든 댓글을 목록 형식으로 볼 수 있도록 하기
- 작성 날짜 기준으로 내림차순 정렬하기
7. 댓글 작성
- 댓글 내용을 비워둔 채 댓글 작성 API를 호출하면 "댓글 내용을 입력해주세요" 라는 메세지를 return하기
- 댓글 내용을 입력하고 댓글 작성 API를 호출한 경우 작성한 댓글을 추가하기
8. 댓글 수정
- 댓글 내용을 비워둔 채 댓글 수정 API를 호출하면 "댓글 내용을 입력해주세요" 라는 메세지를 return하기
- 댓글 내용을 입력하고 댓글 수정 API를 호출한 경우 작성한 댓글을 수정하기
9. 댓글 삭제
- 원하는 댓글을 삭제하기

본격 API 만들기 과제가 주어졌다.
이번 과제 역시 매순간 고민과 에러의 연속...

MongoServerError: E11000 duplicate key error collection: mj_posts.posts index: postId_1 dup key: { postId: null } 에러

C:\Users\82102\Desktop\sparta\Node.js_입문주차\mj_posts\node_modules\mongodb\lib\operations\insert.js:53
                return callback(new error_1.MongoServerError(res.writeErrors[0]));
                                ^

MongoServerError: E11000 duplicate key error collection: mj_posts.posts index: postId_1 dup key: { postId: null }

postId: {
    type: mongoose.Schema.Types.ObjectId,
    unique: true,
  }

스키마 파일에서 postId 라는 키를 분명히 지우고 코드를 실행시켰는데 에러가 발생했다.

알고 보니 MongoDB에서는 스키마에서 삭제를 한다고 하더라도 콜렉션에는 이전 데이터가 그대로 남아 있어서 데이터가 매칭이 안 돼서 나타나는 에러라고 한다.

Studio 3T에서 해당 콜렉션을 지우고 다시 실행시켰더니 에러가 사라졌다.
명령어로 해당 키만 지우는 방법이 있다고 하는데... 어떻게 해야 할지 모르겠어서 그냥 콜렉션을 삭제해버렸다.

MongoDB 특정 필드의 값만 찾아서 보여주기 (find 활용)

전체 게시글을 조회할 때 콜렉션에 있는 모든 정보(패스워드, 게시글 id 등을 포함)가 아니라 일부만 보여주고 싶었다.

구글링을 해서 find({}, {보여주고 싶은 필드: 1, 보여주고 싶지 않은 필드: 0})로 처리하면 된다길래 다음과 같이 해봤다.

const posts = await Posts
					.find({},{_id: 0, title: 1, userName: 1, password: 0, content: 0, createdAt: 1, __v:0

그런데 구현이 안되길래 또 다시 구글링...
MongDB 공식 홈페이지에서 똑같은 Q&A를 찾아서 해결했다!

출처: https://www.mongodb.com/community/forums/t/projection-does-not-allow-exclusion-inclusion-together/31756

It does not allow the mixing of inclusions and exclusion when returning a result. You must either:

Choose to return results only containing the movie title
OR
Choose to return movies with the id and genres excluded.
The query that you have stated

db.movies.find({“cast.0”:“Jeff Bridges”},{title:1,_id:0,genre:0})
Is equivalent to;

db.movies.find({“cast.0”:“Jeff Bridges”},{title:1})
Though the ID is returned by default…
Actually ID is the only field that you can mix inclusions and exclusions, so this is possible:

**db.movies.find({“cast.0”:“Jeff Bridges”},{_id:0,title:1})**

위 내용을 풀이해보면 _id 값은 디폴트이므로 보여주고 싶지 않은 경우 반드시 0으로 값을 적어줘야 한다. 하지만 나머지 키들의 경우 보여주고 싶은 값만 1로 처리해주면 된다. (나머지는 0을 써줄 필요가 없다!)

그래서 다음과 같이 수정했더니 해결!

const posts = await Posts.find({},{_id: 0, title: 1, userName: 1, createdAt: 1});

To-do list

  • 개인 과제 마무리, AWS 서버 배포
  • 과제 리뷰 듣기
  • 알고리즘 문제 풀기
profile
Back-End Wep Developer. 꾸준함이 능력이다.

0개의 댓글