MongoDBで重複レコードを見つける


116

mongoコレクションで重複フィールドをどのように見つけますか?

「名前」フィールドが重複していないか確認したいのですが。

{
    "name" : "ksqn291",
    "__v" : 0,
    "_id" : ObjectId("540f346c3e7fc1054ffa7086"),
    "channel" : "Sales"
}

どうもありがとう!


5
この質問の重複フラグは不当です。この質問では、重複するレコードを見つけるのではなく、見つける方法を尋ねます。
Harry King

回答:


209

上の集約を使用nameして取得するnamecount > 1

db.collection.aggregate(
    {"$group" : { "_id": "$name", "count": { "$sum": 1 } } },
    {"$match": {"_id" :{ "$ne" : null } , "count" : {"$gt": 1} } }, 
    {"$project": {"name" : "$_id", "_id" : 0} }
)

結果を重複の多い順に並べ替えるには:

db.collection.aggregate(
    {"$group" : { "_id": "$name", "count": { "$sum": 1 } } },
    {"$match": {"_id" :{ "$ne" : null } , "count" : {"$gt": 1} } }, 
    {"$sort": {"count" : -1} },
    {"$project": {"name" : "$_id", "_id" : 0} }     
)

「name」以外の列名で使用するには、「$ name」を「$ column_name」に変更します


1
"$match": {"_id" :{ "$ne" : null } -ステートメントの2番目の部分は結果のフィルタリングで十分なので、ここでは不要です。だから、持っているグループをチェックするだけで十分count > 1です。
BatScream 2014年

5
Tks @BatScream。{"$ ne":null}は、 'name'がnullまたは存在しない場合に備えて存在します 集計もnullをカウントします。
anhlc 2014年

1
ようこそ。しかし、なぜ_idフィールドを確認してください。group操作後は常にnullでないことが保証されます。
BatScream 2014年

4
_id以下からのドキュメントの$groupステージはnullにすることができます。
wdberkeley 2014年

1
これの出力はどうなりますか?私が実行した場合、必要なのはすべてのドキュメントを取得することです。重複したIDと名前のみが必要です。
Kannan T 2017

24

名前の検索にlistduplicate、次のaggregateパイプラインを使用します。

  • Group類似したすべてのレコードname
  • Matchgroupsより大きい記録を持つもの1
  • 次に、重複groupするprojectすべての名前をarray

コード:

db.collection.aggregate([
{$group:{"_id":"$name","name":{$first:"$name"},"count":{$sum:1}}},
{$match:{"count":{$gt:1}}},
{$project:{"name":1,"_id":0}},
{$group:{"_id":null,"duplicateNames":{$push:"$name"}}},
{$project:{"_id":0,"duplicateNames":1}}
])

o / p:

{ "duplicateNames" : [ "ksqn291", "ksqn29123213Test" ] }

10

大規模なデータベースがあり、属性名が一部のドキュメントにのみ存在する場合、anhicの回答は非常に非効率的です。

効率を向上させるために、集計に$ matchを追加できます。

db.collection.aggregate(
    {"$match": {"name" :{ "$ne" : null } } }, 
    {"$group" : {"_id": "$name", "count": { "$sum": 1 } } },
    {"$match": {"count" : {"$gt": 1} } }, 
    {"$project": {"name" : "$_id", "_id" : 0} }
)

3
db.getCollection('orders').aggregate([  
    {$group: { 
            _id: {name: "$name"},
            uniqueIds: {$addToSet: "$_id"},
            count: {$sum: 1}
        } 
    },
    {$match: { 
        count: {"$gt": 1}
        }
    }
])

最初のグループフィールドに従ってグループを照会します。

次に、一意のIDをチェックしてカウントします。countが1より大きい場合、フィールドはコレクション全体で重複しているため、$ matchクエリで処理されます。


1
私もこれをうまく機能させることができませんでした。反対投票!
Mathieu G

この投稿は古いですが、役立つかもしれません。これをチェックしてみてください。私はこれについて1つのブログに出くわしました。ぜひご覧ください。compose.com/articles/finding-duplicate-documents-in-mongodb
Aman shrivastava

私はそれを動作させることができました-確認された動作バージョンに更新するために編集されました。
AL Strine
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.