MongoDB에서 중복 데이터 입력을 방지하고 싶다면 고유 인덱스(Unique Index)를 활용할 수 있습니다. 인덱스를 생성할 때 unique: true 옵션을 설정하면 해당 필드에 동일한 값이 두 번 저장되지 않도록 강제할 수 있습니다.
고유 인덱스 생성 방법
먼저 컬렉션을 생성하면서 FirstName 필드에 고유 인덱스를 만들어 보겠습니다. 이때 sparse: true 옵션을 함께 사용하면 해당 필드가 없는 문서는 인덱스 대상에서 제외됩니다.
> db.demo658.createIndex({FirstName:1},{unique:true,sparse:true});
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}문서 삽입 및 중복 검증 테스트
이제 문서를 하나씩 삽입해 보겠습니다. 첫 번째와 두 번째 문서는 서로 다른 FirstName 값을 가지고 있으므로 정상적으로 저장됩니다.
> db.demo658.insertOne({"FirstName":"John","LastName":"Smith"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5ea067144deddd72997713d9")
}
> db.demo658.insertOne({"FirstName":"Adam","LastName":"Smith"});
{
"acknowledged" : true,
"insertedId" : ObjectId("5ea0671c4deddd72997713da")
}하지만 세 번째 문서처럼 이미 존재하는 "John"이라는 FirstName 값을 가진 문서를 삽입하면 어떻게 될까요?
> db.demo658.insertOne({"FirstName":"John","LastName":"Doe"});
2020-04-22T21:17:46.072+0530 E QUERY [js] WriteError: E11000 duplicate key error collection: onlinecustomertracker.demo658 index: FirstName_1 dup key: { : "John" } :
WriteError({
"index" : 0,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: onlinecustomertracker.demo658 index: FirstName_1 dup key: { : \"John\" }",
"op" : {
"_id" : ObjectId("5ea067224deddd72997713db"),
"FirstName" : "John",
"LastName" : "Doe"
}
})
WriteError@src/mongo/shell/bulk_api.js:461:48
Bulk/mergeBatchResults@src/mongo/shell/bulk_api.js:841:49
Bulk/executeBatch@src/mongo/shell/bulk_api.js:906:13
Bulk/this.execute@src/mongo/shell/bulk_api.js:1150:21
DBCollection.prototype.insertOne@src/mongo/shell/crud_api.js:252:9
@(shell):1:1위 출력 결과에서 볼 수 있듯이 E11000 duplicate key error 오류가 발생하며 삽입이 거부됩니다. 이는 고유 인덱스가 정상적으로 작동하여 중복 값을 차단했다는 의미입니다.
저장된 문서 확인하기
find() 메서드를 사용해 컬렉션의 모든 문서를 조회해 보겠습니다.
> db.demo658.find();
실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5ea067144deddd72997713d9"), "FirstName" : "John", "LastName" : "Smith" }
{ "_id" : ObjectId("5ea0671c4deddd72997713da"), "FirstName" : "Adam", "LastName" : "Smith" }중복으로 삽입을 시도했던 "John", "Doe" 문서는 저장되지 않고, 처음 삽입된 두 개의 문서만 남아 있는 것을 확인할 수 있습니다.
정리
createIndex()메서드에{unique: true}옵션을 지정하면 고유 인덱스가 생성됩니다.- 고유 인덱스가 설정된 필드에 중복 값이 삽입되면 E11000 오류가 발생합니다.
sparse: true옵션을 추가하면 해당 필드가 없는 문서는 인덱스 제약 조건에서 제외됩니다.