MongoDB 다중 업데이트 오류란?
MongoDB에서 조건 없이 컬렉션의 모든 문서를 한 번에 업데이트하려고 할 때 'multi update is only allowed with $ operators'(다중 업데이트는 $ 연산자에서만 작동합니다)라는 오류가 발생하는 경우가 있습니다. 이 오류는 여러 문서를 수정할 때 업데이트 연산자($set 등)를 사용하지 않았기 때문에 발생합니다.
이 문제는 $set 연산자를 사용하면 간단히 해결할 수 있습니다. 기본 문법은 다음과 같습니다.
db.yourCollectionName.update({ }, { '$set': { "yourFieldName": "yourValue" } }, false, true);여기서 마지막 두 인자의 의미는 다음과 같습니다.
- false: upsert 옵션으로, 조건에 맞는 문서가 없을 경우 새로 삽입하지 않습니다.
- true: multi 옵션으로, 조건에 맞는 모든 문서를 업데이트합니다.
예제용 컬렉션 생성하기
위 문법을 실제로 이해하기 위해 예제 컬렉션을 만들어 보겠습니다. 다음 쿼리로 문서가 포함된 컬렉션을 생성합니다.
> db.unconditionalUpdatesDemo.insertOne({"ClientName":"Larry","ClientAge":24});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c8eb7372f684a30fbdfd557")
}
> db.unconditionalUpdatesDemo.insertOne({"ClientName":"Mike","ClientAge":26});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c8eb73f2f684a30fbdfd558")
}
> db.unconditionalUpdatesDemo.insertOne({"ClientName":"Sam","ClientAge":27});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c8eb7462f684a30fbdfd559")
}
> db.unconditionalUpdatesDemo.insertOne({"ClientName":"Carol","ClientAge":29});
{
"acknowledged" : true,
"insertedId" : ObjectId("5c8eb7502f684a30fbdfd55a")
}컬렉션의 모든 문서 조회하기
find() 메서드를 사용하여 컬렉션의 모든 문서를 출력해 보겠습니다.
> db.unconditionalUpdatesDemo.find().pretty();
실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5c8eb7372f684a30fbdfd557"),
"ClientName" : "Larry",
"ClientAge" : 24
}
{
"_id" : ObjectId("5c8eb73f2f684a30fbdfd558"),
"ClientName" : "Mike",
"ClientAge" : 26
}
{
"_id" : ObjectId("5c8eb7462f684a30fbdfd559"),
"ClientName" : "Sam",
"ClientAge" : 27
}
{
"_id" : ObjectId("5c8eb7502f684a30fbdfd55a"),
"ClientName" : "Carol",
"ClientAge" : 29
}$set 연산자로 전체 문서 업데이트하기
이제 조건 없이 모든 문서를 업데이트하는 쿼리를 실행해 보겠습니다. 첫 번째 인자로 빈 조건({ })을 넣고, $set 연산자와 함께 multi 옵션을 true로 설정합니다.
> db.unconditionalUpdatesDemo.update({ }, {'$set': {"ClientName": "Robert" }}, false, true);
WriteResult({ "nMatched" : 4, "nUpserted" : 0, "nModified" : 4 })결과를 보면 nMatched: 4, nModified: 4로, 4개의 문서가 모두 성공적으로 수정되었음을 확인할 수 있습니다.
업데이트 결과 확인하기
find() 메서드로 다시 문서를 조회하여 변경 사항을 확인해 보겠습니다.
> db.unconditionalUpdatesDemo.find().pretty();
실행 결과는 다음과 같습니다.
{
"_id" : ObjectId("5c8eb7372f684a30fbdfd557"),
"ClientName" : "Robert",
"ClientAge" : 24
}
{
"_id" : ObjectId("5c8eb73f2f684a30fbdfd558"),
"ClientName" : "Robert",
"ClientAge" : 26
}
{
"_id" : ObjectId("5c8eb7462f684a30fbdfd559"),
"ClientName" : "Robert",
"ClientAge" : 27
}
{
"_id" : ObjectId("5c8eb7502f684a30fbdfd55a"),
"ClientName" : "Robert",
"ClientAge" : 29
}모든 문서의 ClientName 필드가 "Robert"로 변경된 것을 확인할 수 있습니다.
정리 및 참고 사항
핵심은 여러 문서를 업데이트할 때는 반드시 $set과 같은 업데이트 연산자를 사용해야 한다는 점입니다. 연산자 없이 일반 문서 형태로 값을 지정하면 MongoDB는 이를 문서 전체 교체로 해석하며, multi 옵션과 함께 사용할 수 없어 위와 같은 오류가 발생합니다.
또한 최신 버전의 MongoDB(4.2 이상)에서는 updateMany() 메서드를 사용하는 것이 권장됩니다. 예를 들면 다음과 같습니다.
db.unconditionalUpdatesDemo.updateMany({}, { $set: { "ClientName": "Robert" } });updateMany()는 별도의 multi 옵션 설정 없이 자동으로 조건에 맞는 모든 문서를 업데이트하므로 더욱 직관적이고 안전하게 사용할 수 있습니다.