Temukan catatan duplikat di MongoDB

116

Bagaimana saya menemukan bidang duplikat dalam koleksi mongo.

Saya ingin memeriksa apakah ada bidang "nama" yang duplikat.

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

Terimakasih banyak!

Chris
sumber
5
Bendera duplikat untuk pertanyaan ini tidak layak. Pertanyaan ini menanyakan bagaimana menemukan catatan duplikat, bukan mencegahnya.
Harry King

Jawaban:

210

Gunakan agregasi namedan lanjutkan namedengan count > 1:

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

Untuk mengurutkan hasil dari paling banyak hingga paling sedikit duplikat:

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

Untuk menggunakan nama kolom selain "name", ubah " $ name " menjadi " $ column_name "

anhlc
sumber
1
"$match": {"_id" :{ "$ne" : null } - tidak diperlukan di sini, karena bagian kedua dari pernyataan akan cukup memfilter hasilnya. Jadi hanya memeriksa kelompok yang count > 1akan dilakukan.
BatScream
5
Tks @BatScream. {"$ ne": null} apakah di sana kalau-kalau 'nama' nol atau tidak ada. Agregasi juga akan menghitung nol.
anhlc
1
Selamat datang. Tapi mengapa harus memeriksa _idlapangan. Itu selalu dijamin tidak null setelah groupoperasi.
BatScream
4
The _iddokumen dari $grouptahap bisa null.
wdberkeley
1
Apa hasil dari ini? Jika saya menjalankan saya mendapatkan semua dokumen yang saya butuhkan adalah saya hanya menginginkan id / nama yang digandakan.
Kannan T
24

Anda dapat menemukan listdari duplicatenama-nama menggunakan berikut aggregatepipa:

  • Groupsemua catatan memiliki kesamaan name.
  • Matchmereka yang groupsmemiliki catatan lebih besar dari 1.
  • Kemudian grouplagi ke projectsemua nama duplikat sebagai file array.

Kode:

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" ] }
BatScream
sumber
10

Jawaban yang diberikan anhic bisa sangat tidak efisien jika Anda memiliki database yang besar dan nama atribut hanya ada di beberapa dokumen.

Untuk meningkatkan efisiensi, Anda dapat menambahkan kecocokan $ ke agregasi.

db.collection.aggregate(
    {"$match": {"name" :{ "$ne" : null } } }, 
    {"$group" : {"_id": "$name", "count": { "$sum": 1 } } },
    {"$match": {"count" : {"$gt": 1} } }, 
    {"$project": {"name" : "$_id", "_id" : 0} }
)
Juanín
sumber
3
db.getCollection('orders').aggregate([  
    {$group: { 
            _id: {name: "$name"},
            uniqueIds: {$addToSet: "$_id"},
            count: {$sum: 1}
        } 
    },
    {$match: { 
        count: {"$gt": 1}
        }
    }
])

Kueri Grup Pertama grup menurut bidang.

Kemudian kami memeriksa Id unik dan menghitungnya, Jika hitungan lebih besar dari 1 maka bidang tersebut duplikat di seluruh koleksi sehingga hal itu akan ditangani oleh $ match query.

Aman shrivastava
sumber
1
belum bisa membuat ini bekerja untuk saya juga. Bawah voting!
Mathieu G
Posting ini sudah tua tapi mungkin bisa membantu seseorang. lihat ini saya akan memeriksa di lokal saya itu berfungsi. Bahkan saya menemukan satu blog tentang ini. Mohon dilihat. compose.com/articles/finding-duplicate-documents-in-mongodb
Aman shrivastava
Saya bisa membuatnya bekerja - diedit untuk memperbarui ke versi kerja yang dikonfirmasi.
AL Strine