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!


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 "


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" ] }

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} }
)

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.


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.