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

MongoDB 3.x에서 중복 레코드를 제거하는 방법

MongoDB 3.x에서 중복 레코드 찾기 및 제거하기

MongoDB 컬렉션에 동일한 값이 여러 번 저장되어 있는 경우, aggregate() 메서드와 $group, $addToSet 연산자를 조합하면 중복 레코드를 손쉽게 식별하고 제거할 수 있습니다.

먼저 예제로 사용할 컬렉션을 생성하고 문서를 삽입해 보겠습니다.

> db.demo438.insertOne({"FirstName":"Chris"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e775c37bbc41e36cc3caea1")
}
> db.demo438.insertOne({"FirstName":"David"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e775c3dbbc41e36cc3caea2")
}
> db.demo438.insertOne({"FirstName":"Chris"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e775c40bbc41e36cc3caea3")
}
> db.demo438.insertOne({"FirstName":"Bob"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e775c44bbc41e36cc3caea4")
}
> db.demo438.insertOne({"FirstName":"David"});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e775c47bbc41e36cc3caea5")
}

1단계: 전체 문서 확인

find() 메서드를 사용해 컬렉션의 모든 문서를 조회합니다.

> db.demo438.find();

실행 결과는 다음과 같습니다. ChrisDavid가 각각 두 번씩 저장되어 있음을 확인할 수 있습니다.

{ "_id" : ObjectId("5e775c37bbc41e36cc3caea1"), "FirstName" : "Chris" }
{ "_id" : ObjectId("5e775c3dbbc41e36cc3caea2"), "FirstName" : "David" }
{ "_id" : ObjectId("5e775c40bbc41e36cc3caea3"), "FirstName" : "Chris" }
{ "_id" : ObjectId("5e775c44bbc41e36cc3caea4"), "FirstName" : "Bob" }
{ "_id" : ObjectId("5e775c47bbc41e36cc3caea5"), "FirstName" : "David" }

2단계: 집계 파이프라인으로 중복 그룹화

다음 쿼리는 $group으로 FirstName 값을 기준으로 문서를 묶고, $addToSet을 사용해 각 그룹에 속한 모든 _id를 배열로 수집합니다.

> db.demo438.aggregate([ { "$group":{ _id:{FirstName:"$FirstName"}, DuplicateValueIds:{$addToSet:"$_id"} } } ]);

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

{ "_id" : { "FirstName" : "David" }, "DuplicateValueIds" : [ ObjectId("5e775c47bbc41e36cc3caea5"), ObjectId("5e775c3dbbc41e36cc3caea2") ] }
{ "_id" : { "FirstName" : "Bob" }, "DuplicateValueIds" : [ ObjectId("5e775c44bbc41e36cc3caea4") ] }
{ "_id" : { "FirstName" : "Chris" }, "DuplicateValueIds" : [ ObjectId("5e775c40bbc41e36cc3caea3"), ObjectId("5e775c37bbc41e36cc3caea1") ] }

결과를 보면 DavidChris 그룹에는 두 개의 ObjectId가 포함되어 있어 중복이 존재한다는 것을 알 수 있습니다.

3단계: 실제로 중복 레코드 삭제하기

중복을 식별했다면, 각 그룹에서 하나의 문서만 남기고 나머지를 삭제하는 방식으로 정리할 수 있습니다. 아래 예시는 그룹별 첫 번째 _id를 유지하고 나머지 문서를 삭제하는 코드입니다.

> db.demo438.aggregate([
...   { "$group": {
...       _id: { FirstName: "$FirstName" },
...       ids: { $addToSet: "$_id" },
...       count: { $sum: 1 }
...   }},
...   { "$match": { count: { $gt: 1 } } }
... ]).forEach(function(doc) {
...   doc.ids.shift(); // 첫 번째 문서는 유지
...   db.demo438.remove({ _id: { $in: doc.ids } });
... });

삭제 후 다시 find()를 실행하면 각 이름이 하나씩만 남아 있는 것을 확인할 수 있습니다.

정리

  • $group + $addToSet 조합으로 중복 데이터를 그룹별로 식별할 수 있습니다.
  • $match$sum을 함께 사용하면 중복 개수가 2개 이상인 그룹만 필터링할 수 있습니다.
  • 실무에서는 대량의 데이터를 다룰 때 삭제 작업 전 반드시 백업을 수행하는 것이 안전합니다.