항해99/TIL

20230301 TIL

공대루루 2023. 3. 1. 22:10

문제점(1)

게시글에 연결되어 있는 댓글을 수정하기 위해서 commentId를 사용해서 데이터를 받아오려고 하는데 find()를 써도 안되고 findOne()을 써도 안되고 findId()를 써도 안된다. 계속 여기에 사용할 수 없는 명령어라는 에러가 생긴다.... 왜지? 분명 배열 안에 객체가 들어가있는 형태로 데이터는 잘 쌓이고 있는데............???????????????

해결방안

데이터를 배열의 형태로 잘 쌓이고 있었지만 post schema에 이 값들이 배열이라고 설정해주지 않아서 몽구스가 이제 배열이라고 인식을 못했던 것이었다...........바보시키

먼저 post schema에 가서 형태를 배열로 바꿔주었다. 아래 처럼 간단하게 comment schema에 []를 붙여주면 된다.

const commentSchema = require('./comment.js');
const postsSchema = new mongoose.Schema({
    
    user: {
        type: String,
        required: true,
    },
    comments: [commentSchema]  //여기에 원래 commentSchema 로만 들어가 있었다..
});

이후 find 명령어로 값을 찾았더니 바로 잘~~ 찾아왔다!!  이제 이걸로 수정 작업만 마무리하면 과제 끝!

const existsPosts = await Posts.findById(postId); //postId로 특정 post 불러오기
//commentId로 특정 comment 불러오기
const existsComments = await existsPosts.comments.find((comment) => String(comment.commentId) === commentId)

알게된점

내눈에 배열처럼 보인다고 컴퓨터도 그걸 배열이라고 생각하지 않을 수도 있다!! schema 작성할 때 항상 이생각을 하면서 꼼꼼하게 체크해야 겠다!! 


문제점(2)

아래의 코드처럼 findOneAndUpdate()을 사용해서 수정할 내용을 업데이트 하려고 하는데 에러는 생기지 않는데 database에서 업데이트를 하지 못하고 있다... 뭔가 명령어가 기준점을 데이터내에서 찾지를 못하고 있는 것 같은데 왜 못찾는건지 알수가 없다... 바보야 좀 찾아봐 똑같은 글자잖아.....

await Posts.findOneAndUpdate({_id:postId,"comments.commentId": commentId},{ $set : {"comments.$.content": content }})

☆ 위의 코드에서 $는 배열에서 매칭된 인덱스를 나타낸다.  $set은 데이터의 일부분을 업데이트하겠다는 것을 나타내며, comments.$.content는 배열의 해당 인덱스의 content 필드를 업데이트하겠다는 것을 나타낸다.

해결방법

내 예상대로 명령어가 postId와 commentId를 데이터내에서 찾지 못하고 있었다... console.log()로 찍어봤을 때 두개의 값 모두 new ObjectId("63fee393f9c5bd2a18d310d3") 이런식으로 들어온다. 항해99 기술매니저님하고 같이 문제를 해결하려고 보고있다가 filter가 데이터를 제대로 읽지는 못하는걸까요... 라고 말했더니 매니저님이 바로 어떻게 하면 될 지 찾아주셨다!!!! (천재 기술매니저님은 AI 보다 문제를 제대로 해결해주신다 사랑해요진짜...

게시글 수정을 할 때에도 postId를 사용했는데 그때는 {_id:postId}로 입력해서 사용해도 자동으로 인식을 했었는데 sub-schema를 수정할 때에는 그걸 자동으로 인식하지 못하는 것 같다.

그래서 값들을 하나하나 mongoose.Types.ObjectId()로 묶어주었고 아래와 같다. 삭제 할때에도 똑같이 해주었다!!

await Posts.findOneAndUpdate({_id:mongoose.Types.ObjectId(postId) ,"comments.commentId": mongoose.Types.ObjectId(commentId)},{ $set : {"comments.$.content": content }})

알게된점

sub-schema를 사용할 때에는 데이터를 좀 더 확실하게 정의를 해주어야 하는 것 같다. 


☆오늘 알게된 것★

mongoose로 데이터 제어하기

// find 안에 callback 함수를 넣어주면 callback 함수에 해당하는 요소를 찾아준다.
await Model.find(callback)

//find 안에 {key:value}형태의 filter를 넣어주면 해당하는 요소를 찾아준다.
await Model.find([filter])

//filter와 update 둘다 {key : value} 형태로 값을 줄 수 있다.
//filter에 해당하는 값을 찾아서 업데이트해준다.
await Model.findOneAndUpdate(filter, { $set: { key: value } })