본문 바로가기

과목/빅데이터

Mongoose에서 findOneAndUpdate 사용하기

RDBMS에 익숙해지기 위해, MVC를 명확히 하기 위해 사용한 Mongoose에선 arrayFilters를 못 쓰는 것 같다...

arrayFilters는 MongoDB에서 사용할 수 있는 함수다. 도큐먼트 내에 필드가 있고 그 필드가 array로 구성되어 있는 경우 그 array의 각 원소에 접근하기 위해 쓰는 함수다.


여튼 MongoDB에선 매우 잘 실행되었지만 Mongoose에선 arrayFilters가 먹히지 않아서 다른 방법을 찾았다.


일단 findOneAndUpdate()라는 함수에서 첫 인자로 어떤 도큐먼트를 찾을지 정해줬다.

arrayFilters로 해당 도큐먼트의 array 원소 중 id가 일치하는 애를 찾았다. 그 원소의 memo라는 field를 갱신해줬다.


혹시나 하고 Mongoose를 6.x.x 버전으로 업데이트 했는데 안된다..


안되는 코드..

1
2
3
4
5
6
7
8
9
10
database.BoardModel.findOneAndUpdate(
    {_id:contentid},//1. 글 찾기
    {$set:{"comments.$[elem].memo":modifiedtext}},//해당 배열 요소의 memo에 값 쓰기
    {arrayFilters:[{"elem._id":replyid}],new:true},//2. 배열의 요소 중 id 일치하는 것 찾기
    function(err,modified){
        if(err) throw err;
        console.log('modified',modified);
        //console.log('modified',modified.comments);
        res.send({reply:modified.comments});
});
cs




위 코드가 안먹혀서... 삽질한 뒤에 stackoverflow를 뒤져 방법을 찾았다.

우선 첫 객체에서 원하는 것을 찾는다. {_id:contentid,comments:{$elemMatch:{_id:replyid}}},

document를 _id로 찾고 거기에 있는 comments라는 field의 원소를 $elemMatch로 다 뒤져서 replyid와 일치하는 지 본다.

일치하는 녀석의 memo field를 $set을 사용해서 갱신해준다. {$set:{"comments.$.memo":modifiedtext}},


아마 저 $는 4$!가 아니라 검색된 원소를 말하는 것 같다. comments라는 array field에서 검색된 원소 중에서 memo를 수정한다는 의미.


되게 만든 코드!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
database.BoardModel.findOneAndUpdate(
    {_id:contentid,comments:{$elemMatch:{_id:replyid}}},
    {$set:{"comments.$.memo":modifiedtext}},
    function(err,results){
        if(err) throw err;
        console.log(results);
        if(results){
            database.BoardModel.find({_id:contentid},function(err,reply){
                if(err) throw err;
                console.log('reply after modifying',reply[0].comments);
                res.send({reply:reply[0].comments});
            });
        }
});
cs




findOneAndUpdate 문서 https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndUpdate/

stackoverflow https://stackoverflow.com/questions/48215167/node-js-mongoose-update-with-arrayfilters

https://stackoverflow.com/questions/51324876/arrayfilters-in-mongodb

github https://github.com/Automattic/mongoose/issues/5986 이렇게 해도 안되는 것 같다..

ObjectId를 제대로 인식 못한 건가해서 해봤는데도 안됨.

https://stackoverflow.com/questions/41501939/how-to-update-a-array-value-in-mongoose

update로 하는 방법(안해봄)

https://stackoverflow.com/questions/15691224/mongoose-update-values-in-array-of-objects

결국 이렇게 함

https://stackoverflow.com/questions/16325817/in-mongoose-how-to-filter-an-array-of-objects