MongoDB에서 배열 안에 포함된 특정 태그 레코드를 수정하려면 위치 연산자($)와 함께 update 명령을 사용하면 됩니다. 위치 연산자는 쿼리 조건과 일치하는 첫 번째 배열 요소를 자동으로 찾아 해당 요소만 업데이트해 주기 때문에, 배열 전체를 다시 쓰지 않고도 효율적으로 데이터를 변경할 수 있습니다.
1. 테스트용 컬렉션 생성
먼저 태그 배열을 포함한 문서를 담은 컬렉션을 생성합니다. insertOne() 메서드를 사용하면 됩니다.
> db.demo713.insertOne(
... {
... tags:
... [
... {
... id:101,
... Name:"Tag-1"
... },
... {
... id:102,
... Name:"Tag-3"
... },
... {
... id:103,
... Name:"Tag-3"
... }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5ea8625a5d33e20ed1097b87")
}의도적으로 두 개의 문서에 동일한 이름("Tag-3")이 들어 있어, 이후 업데이트 시 어떤 요소가 수정되는지 확인하기 좋습니다.
2. 현재 문서 조회하기
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 확인할 수 있습니다.
> db.demo713.find();
실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5ea8625a5d33e20ed1097b87"), "tags" : [ { "id" : 101, "Name" : "Tag-1" }, { "id" : 102, "Name" : "Tag-3" }, { "id" : 103, "Name" : "Tag-3" } ] }3. 위치 연산자($)로 태그 업데이트
이제 id가 102인 태그의 Name 값을 "Tag-2"로 변경해 보겠습니다. 핵심은 "tags.$.Name"처럼 $ 기호를 사용하는 것입니다. 이 기호가 쿼리 조건({"tags.id": 102})과 일치하는 배열 요소의 위치를 가리킵니다.
> db.demo713.update({"tags.id":102},{$set:{"tags.$.Name":"Tag-2"}},false,true);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })update 명령에 전달된 세 번째와 네 번째 인자는 각각 upsert와 multi 옵션입니다. 여기서는 upsert를 false로 설정했으므로, 조건에 맞는 문서가 없으면 새 문서를 생성하지 않습니다.
- nMatched: 1 — 조건과 일치한 문서 수
- nUpserted: 0 — 새로 삽입된 문서 없음
- nModified: 1 — 실제로 수정된 문서 수
4. 업데이트 결과 확인
다시 find() 메서드에 pretty()를 붙여 가독성 좋게 출력해 보겠습니다.
> db.demo713.find().pretty();
결과를 보면 id가 102인 태그의 Name만 "Tag-2"로 정상적으로 변경된 것을 확인할 수 있습니다.
{
"_id" : ObjectId("5ea8625a5d33e20ed1097b87"),
"tags" : [
{
"id" : 101,
"Name" : "Tag-1"
},
{
"id" : 102,
"Name" : "Tag-2"
},
{
"id" : 103,
"Name" : "Tag-3"
}
]
}정리
이처럼 MongoDB에서는 $set과 위치 연산자 $를 조합하면 배열 내부의 특정 요소만 골라서 손쉽게 업데이트할 수 있습니다. 참고로 최신 버전의 MongoDB에서는 update() 대신 updateOne(), updateMany() 같은 메서드 사용이 권장되며, 동작 원리는 동일하게 적용됩니다.