MongoDB의 findOneAndUpdate() 메서드는 조건에 일치하는 문서 중 단 하나의 문서만 업데이트할 때 사용합니다. 컬렉션 내에 동일한 조건을 만족하는 문서가 여러 개 있더라도, 이 메서드는 가장 먼저 발견된 문서 한 건에만 업데이트를 적용합니다.
실제 예제를 통해 findOneAndUpdate()의 동작 방식을 살펴보겠습니다.
1. 컬렉션 생성 및 문서 삽입
먼저 insertOne() 메서드를 사용해 demo349 컬렉션을 생성하고 문서들을 삽입합니다.
db.demo349.insertOne({"Name":"Chris","Marks":56});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e55384af8647eb59e5620b4")
}
> db.demo349.insertOne({"Name":"David","Marks":78});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e553853f8647eb59e5620b5")
}
> db.demo349.insertOne({"Name":"Chris","Marks":89});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e55385af8647eb59e5620b6")
}
> db.demo349.insertOne({"Name":"David","Marks":54});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e55385ff8647eb59e5620b7")
}위 코드를 실행하면 Name과 Marks 필드를 가진 문서 4개가 컬렉션에 저장됩니다. 참고로 "Chris"와 "David"라는 이름이 각각 두 번씩 등장하는데, 이는 findOneAndUpdate()가 여러 개의 일치 문서 중 오직 하나만 수정한다는 점을 보여주기 위함입니다.
2. 전체 문서 조회
find() 메서드를 사용해 컬렉션의 모든 문서를 확인합니다.
> db.demo349.find();
실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5e55384af8647eb59e5620b4"), "Name" : "Chris", "Marks" : 56 }
{ "_id" : ObjectId("5e553853f8647eb59e5620b5"), "Name" : "David", "Marks" : 78 }
{ "_id" : ObjectId("5e55385af8647eb59e5620b6"), "Name" : "Chris", "Marks" : 89 }
{ "_id" : ObjectId("5e55385ff8647eb59e5620b7"), "Name" : "David", "Marks" : 54 }3. findOneAndUpdate()로 문서 업데이트
이제 Name이 "David"인 문서를 찾아 Marks 값을 10 증가시키는 쿼리를 실행합니다. $inc 연산자는 지정한 필드의 값을 입력한 숫자만큼 증가(음수면 감소)시킵니다.
> db.demo349.findOneAndUpdate({ "Name" : "David" },{$inc:{Marks:10}});
{
"_id" : ObjectId("5e553853f8647eb59e5620b5"),
"Name" : "David",
"Marks" : 78
}여기서 주목할 점은 반환된 문서의 Marks 값이 78, 즉 업데이트 이전의 값이라는 것입니다. findOneAndUpdate()는 기본적으로 수정되기 전의 원본 문서를 반환합니다. 만약 업데이트된 최신 문서를 받고 싶다면 옵션으로 { returnNewDocument: true }(또는 몽고드라이버에서 returnDocument: 'after')를 지정하면 됩니다.
4. 업데이트 결과 확인
find() 메서드로 다시 전체 문서를 조회해 변경 사항을 확인합니다.
> db.demo349.find();
실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5e55384af8647eb59e5620b4"), "Name" : "Chris", "Marks" : 56 }
{ "_id" : ObjectId("5e553853f8647eb59e5620b5"), "Name" : "David", "Marks" : 88 }
{ "_id" : ObjectId("5e55385af8647eb59e5620b6"), "Name" : "Chris", "Marks" : 89 }
{ "_id" : ObjectId("5e55385ff8647eb59e5620b7"), "Name" : "David", "Marks" : 54 }결과를 보면 Name이 "David"인 두 문서 중 _id가 5e553853...인 첫 번째 문서의 Marks 값만 78에서 88로 10 증가했습니다. 나머지 David 문서(Marks: 54)는 그대로 유지되었습니다. 이처럼 findOneAndUpdate()는 조건에 일치하는 문서가 여러 개일 때도 단 하나의 문서만 수정하며, updateMany()와 같이 모든 일치 문서를 변경하지 않는다는 점이 핵심입니다.