MongoDB'de yinelenen kayıtları bulun


118

Bir mongo koleksiyonunda yinelenen alanları nasıl bulurum.

"Ad" alanlarından herhangi birinin yinelenip yinelenmediğini kontrol etmek istiyorum.

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

Çok teşekkürler!


5
Bu soru için yinelenen bayrak hak edilmemiştir. Bu soru, onları engellemek için değil, yinelenen kayıtların nasıl bulunacağını sorar.
Harry King

Yanıtlar:


213

Üzerinde toplanmasına kullanın nameve almak nameile count > 1:

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

Sonuçları en çok kopyaya göre sıralamak için:

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

"Ad" dışında başka bir sütun adıyla kullanmak için " $ ad " ı " $ sütun_adı " olarak değiştirin


1
"$match": {"_id" :{ "$ne" : null } - burada gereksizdir, çünkü ifadenin ikinci kısmı sonucu filtrelemek yeterli olacaktır. Yani sadece sahip olan grubu kontrol etmek count > 1işe yarar.
BatScream

5
Tks @BatScream. {"$ ne": null}, sadece 'ad' null olması veya olmaması durumunda bulunur. Toplama da boş sayılır.
anhlc

1
Hoşgeldiniz. Ama o zaman neden _idalanı kontrol et . İşlemden sonra her zaman boş olmaması garantilidir group.
BatScream

4
_idBir gelen bir belgenin $groupaşamasında boş olabilir.
wdberkeley

1
Bunun çıktısı ne olacak? Çalıştırırsam, ihtiyacım olan tüm belgeleri alırım, sadece yinelenen kimlik / adlarını istiyorum.
Kannan T

24

Sen bulabilirsiniz listarasında duplicateaşağıdaki kullanarak isimlerin aggregateboru hattı:

  • Groupbenzer olan tüm kayıtlar name.
  • Matchgroupsdaha büyük kayıtlara sahip olanlar 1.
  • Sonra grouptekrar projecttüm yinelenen adlara bir array.

Kod:

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'in verdiği yanıt, büyük bir veritabanınız varsa ve öznitelik adı yalnızca bazı belgelerde mevcutsa çok verimsiz olabilir.

Verimliliği artırmak için, toplamaya bir $ eşleşmesi ekleyebilirsiniz.

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

Birinci Grup Grubu alanlara göre sorgulayın.

Sonra benzersiz kimliği kontrol edip sayarız, eğer sayı 1'den büyükse, alan tüm koleksiyonda kopyalanır, böylece bu şey $ match sorgusu tarafından işlenecek.


1
bunun da benim için çalışmasını sağlayamadı. Aşağı oylama!
Mathieu G

Bu gönderi eski ama birine yardımcı olabilir. Bunu kontrol et, yerelde çalıştığını kontrol edeceğim. Bununla ilgili bir bloga bile rastladım. Lütfen bir göz at. compose.com/articles/finding-duplicate-documents-in-mongodb
Aman shrivastava

Çalışmasını sağladım - onaylanmış çalışan sürüme güncellemek için düzenlendi.
AL Strine
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.