MongoDB 3.xで重複レコードを検出・削除する方法を解説
MongoDB 3.xで重複レコードを削除する方法
MongoDBを運用していると、意図せず重複データが混入することがあります。本記事では、aggregate()(集計フレームワーク)を使って重複レコードを特定する手順と、実際に削除するまでの流れを、サンプルコード付きでわかりやすく解説します。
サンプルコレクションの作成
まずは動作確認用として、意図的に重複を含むドキュメントを持つコレクションを作成します。insertOne()メソッドを使用してドキュメントを挿入していきます。
> 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")
}この時点で、「Chris」と「David」がそれぞれ2件ずつ登録されている状態です。
登録済みドキュメントの確認
find()メソッドを使うと、コレクション内のすべてのドキュメントを表示でき、重複の状況を確認できます。
> db.demo438.find();
実行すると、次のような出力が得られます。
{ "_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" }aggregate()で重複レコードを検出する
MongoDB 3.xで重複レコードを特定するには、次のような集計クエリを使用します。
> db.demo438.aggregate([ { "$group":{ _id:{FirstName:"$FirstName"}, DuplicateValueIds:{$addToSet:"$_id"} } } ]);実行結果は以下のとおりです。同じ「FirstName」に対して複数のObjectIdが紐づいている箇所が、重複しているレコードであることを示しています。
{ "_id" : { "FirstName" : "David" }, "DuplicateValueIds" : [ ObjectId("5e775c47bbc41e36cc3caea5"), ObjectId("5e775c3dbbc41e36cc3caea2") ] }
{ "_id" : { "FirstName" : "Bob" }, "DuplicateValueIds" : [ ObjectId("5e775c44bbc41e36cc3caea4") ] }
{ "_id" : { "FirstName" : "Chris" }, "DuplicateValueIds" : [ ObjectId("5e775c40bbc41e36cc3caea3"), ObjectId("5e775c37bbc41e36cc3caea1") ] }クエリのポイント解説
- $group:指定したキー(ここでは「FirstName」)ごとにドキュメントをグループ化するステージです。
- $addToSet:グループ内の値を配列に追加する演算子で、同じ値は自動的に排除されます。
- DuplicateValueIds:各グループに属するドキュメントのObjectId一覧です。この配列の要素数が2以上であれば、そのキーのレコードが重複していると判断できます。
重複レコードを実際に削除する
重複を検出したら、各グループにつき1件を残し、残りを削除します。以下のようにforEach()と組み合わせれば、一括で処理できます。
db.demo438.aggregate([
{ "$group": {
_id: { FirstName: "$FirstName" },
DuplicateValueIds: { $addToSet: "$_id" },
count: { $sum: 1 }
} },
{ "$match": { "count": { "$gt": 1 } } }
]).forEach(function(doc) {
// 配列の先頭1件を取り除き、そのレコードを残す対象とする
doc.DuplicateValueIds.shift();
db.demo438.remove({ "_id": { "$in": doc.DuplicateValueIds } });
});このスクリプトの流れは次のとおりです。
$sumで各グループの件数(count)をカウントする$matchで件数が2以上(重複あり)のグループだけを抽出するshift()で先頭のObjectIdを除外し、それ以外の_idを$in演算子で指定してremove()で一括削除する
まとめ
MongoDB 3.xでは、aggregate()の$groupと$addToSetを組み合わせることで、重複レコードを簡単かつ正確に特定できます。検出結果をもとにforEach()で削除処理を実行すれば、安全にデータを整理できます。
また、今後の重複発生を未然に防ぎたい場合は、ユニークインデックス(例:db.demo438.createIndex({ "FirstName": 1 }, { unique: true }))を作成しておくことも有効です。既存データに重複がある場合はインデックス作成に失敗するため、必ず重複除去を先に行いましょう。
-
Googleドライブの重複ファイルを見つけて削除する方法【保存版ガイド】
GoogleドライブやOneDriveなどのクラウドストレージを日常的に利用している方にとって、重複ファイルは悩みの種になりがちです。Googleドライブを使えば、スマートフォン、タブレット、パソコンなど、どのデバイスからでもファイルの保存・アップロード・閲覧・編集が可能です。しかし、無料で使える容量には限りがあり、重複ファイルが溜まると貴重なストレージをさらに圧迫してしまいます。 特に複数のデバイス間で同期を行っていると、重複ファイルは頻繁に発生します。ファイル数が多い場合、手作業で重複を探し出すのは時間も労力もかかる大変な作業です。本記事では、Googleドライブ内の重複ファイルの見つけ方
-
Excelで重複行を見つけて削除する方法|「重複の削除」機能の使い方
Excelは、データクレンジング(データ整理)のためのツールとして非常に広く活用されています。データクレンジングとは、主に次のような作業を指します。生データ(未加工のデータ)をワークシートに取り込む分析や各種要件に合うようにデータを加工・整形するつまり、データを適切に分析できる状態へと整えることが目的です。データのクレンジングには多岐にわたる手法がありますが、本記事ではその中でも「重複行の削除」に焦点を絞って解説します。Excelで重複行を削除する手順理由はどうであれ、データに重複行が含まれることは珍しくありません。ほとんどの場合、重複行は取り除く必要があります。かつて重複データの削除は手作業