• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

$pull 문법에 대한 질문

23.07.03 19:29 작성 조회수 214

0

선생님, 안녕하세요. 좋은 강의 너무 감사드립니다. 답변도 잘해주셔서 너무 감사드려요!

이번 강의를 들으면서,

Blog.updateMany(
        { "comments.user": userId },
        { $pull: { comments: { user: userId } } }
      )

이 구문이 나왔는데요.

  1. 여기서 updateMany의 첫번째 변수인

{ "comments.user": userId },

는 comments배열의 user가 userId인 객체를 찾는거고,

{ $pull: { comments: { user: userId } } }

여기서도 comments배열안의 user가 userId인 객체를 찾는 거라서, 사실상 같은거를 두번 써준 게 아닌가요??

  1. 그래서

const [user] = await Promise.all([
      User.findOneAndDelete({ _id: userId }),
      Blog.deleteMany({ "user._id": userId }),
      Blog.updateMany(
        { "comments.user": userId }
        // { $pull: { comments: { user: userId } } }
      ),
      Comment.deleteMany({ user: userId }),
    ]);

이런식으로 updateMany의 두번째 변수만

Blog.updateMany(
        { "comments.user": userId }
        // { $pull: { comments: { user: userId } } }
      ),

이런식으로 주석처리를 해줬습니다. 그러자

{
    "err": "Cast to ObjectId failed for value \"2023-07-03T10:17:04.313Z\" (type Date) at path \"user\" because of \"BSONError\""
}

이런 에러가 나왔어요. 그래서 확인해보니,

 User.findOneAndDelete({ _id: userId }),
 Blog.deleteMany({ "user._id": userId }),
 Comment.deleteMany({ user: userId }),

updateMany말고 다른 구문들은 다 실행이 됬더라구요. 그래서 user도 삭제되고 블로그도 삭제되고, comment도 삭제되었지만 blog안의 user가 작성한 comment는 pull되지 않아서 그대로 남아있었습니다.

그런데 여기서 궁금한게, promise.all로 묶어서 같이 실행하면, 하나라도 에러가 나면 바로 실행을 중단하고 에러를 배출한다고 배운 것 같은데, Blog.updateMany의 아래 구문인, Comment.deleteMany가 실행됬더라구요. 트랜잭션까지는 아니더라도 updateMany에서 에러가 나면 Comment.deleteMany는 실행이 안될 줄 알았는데, 이거까지 실행된 거를 보면, Promise.all에서는 전부 순서없이 비동기로 동시에?실행되는 걸까요?

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.07.05

안녕하세요, 인프런 AI 인턴이에요.

먼저, 코드에 대한 설명을 드릴게요.
Blog.updateMany 메서드를 사용하여 “comments.user” 값이 userId인 객체를 찾아와서 comments 배열에서 해당 객체를 제거하는 작업을 수행하고 있습니다.

다음으로, 질문을 통해 이해한 내용에 대해 답변 드리겠습니다.
첫 번째 변수인 { “comments.user”: userId }는 comments 배열의 user가 userId인 객체를 찾고 있습니다.
두 번째 변수인 { $pull: { comments: { user: userId } } }는 comments 배열에서 user가 userId인 객체를 제거해주는 역할을 합니다.

처음에는 두 변수가 같은 작업을 수행하는 것처럼 보입니다. 하지만 실제로 첫 번째 변수는 찾고자 하는 조건을 표현하고, 두 번째 변수는 해당 객체를 제거하기 위한 액션입니다. 따라서, 두 변수는 같은 역할을 하는 것이 아니라 조건과 액션으로 구분되어 있다고 볼 수 있습니다.

또한, 코드 주석 처리 후 에러가 발생한 부분에 대해서도 알려드릴게요.
에러 메시지를 보면 “Cast to ObjectId failed for value \“2023-07-03T10:17:04.313Z\” (type Date) at path \“user\” because of \“BSONError\”” 라고 나옵니다. 이 에러는 user 필드의 값이 ObjectId 타입으로 형변환 실패한 것을 의미합니다.

전체 코드를 보면 User.findOneAndDelete 메서드에서 userId 값을 사용하여 삭제하고 있는 부분이 보입니다. 그런데 해당 userId 값을 “2023-07-03T10:17:04.313Z” 라는 Date 타입으로 인식하려고 하기 때문에 에러가 발생한 것 같습니다. userId 값이 정상적인 ObjectId 형식인지 확인해보시고, 필요에 따라서 형변환 등의 로직을 수정해주셔야 합니다.

더 나아가서, 코드에 대한 수정이 필요하다면 구체적으로 문제점을 알려주시면 도움을 드릴 수 있을 것 같습니다.

다른 궁금한 점이 있다면 언제든지 물어보세요. 좋은 하루 되세요!