MongoDB에서 중복 삽입 방지하기
MongoDB 컬렉션에 중복 데이터가 저장되지 않도록 하려면 인덱스 생성 시 unique: true 옵션, 즉 고유(unique) 제약 조건을 설정하면 됩니다. 이렇게 하면 동일한 값의 중복 삽입이 자동으로 차단됩니다.
기본 문법은 다음과 같습니다.
db.yourCollectionName.ensureIndex({yourFieldName: 1}, {unique: true, dropDups: true})실전 예제로 이해하기
위 문법을 실제로 적용해 보겠습니다. 먼저 demo604라는 컬렉션을 생성하고 FirstName 필드에 고유 인덱스를 설정합니다.
> db.demo604.ensureIndex({FirstName: 1}, {unique: true, dropDups: true});{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}인덱스가 정상적으로 생성되었으므로, 이제 문서를 하나씩 삽입해 보겠습니다.
> db.demo604.insertOne({FirstName:"Chris"});{
"acknowledged" : true,
"insertedId" : ObjectId("5e960887ed011c280a0905d8")
}
> db.demo604.insertOne({FirstName:"Bob"});{
"acknowledged" : true,
"insertedId" : ObjectId("5e96088aed011c280a0905d9")
}
> db.demo604.insertOne({FirstName:"David"});{
"acknowledged" : true,
"insertedId" : ObjectId("5e96088ded011c280a0905da")
}Chris, Bob, David 세 개의 문서가 모두 성공적으로 삽입되었습니다. 그런데 여기서 이미 존재하는 값인 "Chris"를 다시 삽입하려고 하면 어떻게 될까요?
> db.demo604.insertOne({FirstName:"Chris"});
2020-04-15T00:31:35.978+0530 E QUERY [js] WriteError: E11000 duplicate key error collection: test.demo604 index: FirstName_1 dup key: { : "Chris" } :
WriteError({
"index" : 0,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: test.demo604 index: FirstName_1 dup key: { : \"Chris\" }",
"op" : {
"_id" : ObjectId("5e96088fed011c280a0905db"),
"FirstName" : "Chris"
}
})예상대로 E11000 duplicate key error(중복 키 오류)가 발생하며 삽입이 거부됩니다. 이것이 바로 고유 제약 조건이 작동하는 모습입니다.
결과 확인하기
find() 메서드를 사용하여 컬렉션의 모든 문서를 조회해 보겠습니다.
> db.demo604.find();
실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5e960887ed011c280a0905d8"), "FirstName" : "Chris" }
{ "_id" : ObjectId("5e96088aed011c280a0905d9"), "FirstName" : "Bob" }
{ "_id" : ObjectId("5e96088ded011c280a0905da"), "FirstName" : "David" }중복된 "Chris"는 저장되지 않았으며, 처음 삽입된 세 개의 문서만 남아 있는 것을 확인할 수 있습니다.
참고 사항: 최신 MongoDB 버전 사용 시 주의점
최신 버전의 MongoDB를 사용하고 있다면 다음 두 가지를 알아두는 것이 좋습니다.
1. ensureIndex() 대신 createIndex() 사용ensureIndex()는 현재 더 이상 권장되지 않는(deprecated) 메서드입니다. 최신 버전에서는 createIndex()를 사용하세요.
db.demo604.createIndex({FirstName: 1}, {unique: true})2. dropDups 옵션은 MongoDB 4.0부터 제거됨dropDups 옵션은 기존 중복 데이터를 자동으로 삭제해 주는 편리한 기능이었지만, 데이터 손실 위험 때문에 MongoDB 4.0부터 완전히 제거되었습니다. 따라서 기존 컬렉션에 이미 중복 데이터가 있다면, 스크립트나 집계 파이프라인($group 등)을 활용해 중복을 수동으로 정리한 후 고유 인덱스를 생성해야 합니다.