Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB에서 사용자 정의 _id 값으로 문서가 없을 때만 삽입하는 Upsert 방법

MongoDB Upsert란 무엇인가?

MongoDB에서 Upsert는 'Update + Insert'의 합성어로, 조건에 맞는 문서가 존재하면 업데이트하고, 존재하지 않으면 새로 삽입하는 동작을 의미합니다. 특히 사용자가 직접 지정한 _id 값을 사용할 때는 중복 키 오류를 주의해야 합니다.

기본적으로 insert() 메서드를 사용할 때 이미 동일한 _id 값을 가진 문서가 컬렉션에 존재하면 E11000 duplicate key error가 발생합니다. 아래 예제를 통해 이 동작을 자세히 살펴보겠습니다.

1. insert() 사용 시 중복 키 오류 발생

먼저 컬렉션을 생성하고 문서를 삽입해 보겠습니다. 이후 동일한 _id 값을 가진 문서를 다시 삽입하면 오류가 발생하는 것을 확인할 수 있습니다.

> db.customIdDemo.insert({"_id":1,"StudentName":"John"});
WriteResult({ "nInserted" : 1 })
> db.customIdDemo.insert({"_id":1,"StudentName":"Carol"});
WriteResult({
   "nInserted" : 0,
   "writeError" : {
      "code" : 11000,
      "errmsg" : "E11000 duplicate key error collection: admin.customIdDemo index: _id_ dup key: { : 1.0 }"
   }
})
> db.customIdDemo.insert({"_id":2,"StudentName":"Carol"});
WriteResult({ "nInserted" : 1 })
> db.customIdDemo.insert({"_id":2,"StudentName":"Carol"});
WriteResult({
   "nInserted" : 0,
   "writeError" : {
      "code" : 11000,
      "errmsg" : "E11000 duplicate key error collection: admin.customIdDemo index: _id_ dup key: { : 2.0 }"
   }
})
> db.customIdDemo.insert({"_id":3,"StudentName":"Chris"});
WriteResult({ "nInserted" : 1 })

위 실행 결과에서 볼 수 있듯이, _id: 1_id: 2를 다시 삽입하려고 하면 오류 코드 11000과 함께 중복 키 에러가 반환됩니다.

2. find()로 저장된 문서 확인하기

find() 메서드를 사용하여 컬렉션의 모든 문서를 조회할 수 있습니다.

> db.customIdDemo.find().pretty();

실행 결과는 다음과 같습니다.

{ "_id" : 1, "StudentName" : "John" }
{ "_id" : 2, "StudentName" : "Carol" }
{ "_id" : 3, "StudentName" : "Chris" }

3. 해결 방법: upsert 옵션 활용하기

문서가 존재하지 않을 때만 삽입되도록 하려면 update() 계열 메서드에 upsert: true 옵션을 사용하는 것이 좋습니다. 최신 MongoDB 버전에서는 updateOne() 또는 replaceOne() 사용을 권장합니다.

> db.customIdDemo.updateOne(
   { "_id": 4 },
   { $set: { "StudentName": "David" } },
   { upsert: true }
);

위 쿼리는 _id: 4인 문서가 없으므로 새로 삽입됩니다. 반면 이미 존재하는 _id로 실행하면 기존 문서가 업데이트되고 중복 키 오류는 발생하지 않습니다.

정리

  • insert()는 동일한 _id가 존재하면 E11000 중복 키 오류를 반환합니다.
  • 문서가 없을 때만 삽입하고 싶다면 updateOne() 등에 { upsert: true } 옵션을 사용하세요.
  • upsert는 조건부 삽입 로직을 간결하게 구현할 수 있는 MongoDB의 강력한 기능입니다.