Знайдіть дублікати записів у MongoDB


116

Як би я знайшов повторювані поля в колекції mongo.

Я хотів би перевірити, чи будь-яке з полів "ім'я" є дублікатами.

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

Велике дякую!


5
Дублікат прапора для цього питання незаслужений. Це питання задає питання, як знайти дублікати записів, а не запобігти їх.
Гаррі Кінг

Відповіді:


210

Використовуйте агрегацію на nameі отримати nameз count > 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 " на " $ column_name "


1
"$match": {"_id" :{ "$ne" : null } - тут непотрібно, оскільки друга частина твердження буде достатньою фільтруванням результату. Тому буде лише перевірка наявності групи count > 1.
BatScream

5
Tks @BatScream. {"$ ne": null} є лише на випадок, якщо "name" є null або не існує. Агрегація також вважатиметься недійсною.
anhlc

1
Ласкаво просимо. Але тоді навіщо перевіряти _idполе. Завжди гарантується, що після groupоперації не буде нульовим .
BatScream

4
_idДокумента від $groupстадії може бути порожнім.
wdberkeley

1
Що буде результатом цього? Якщо я запускаю, я отримую всі документи, що мені потрібно, я хочу лише дублювати ідентифікатори / імена.
Каннан Т

24

Ви можете знайти listз duplicateімен з допомогою наступного aggregateтрубопроводу:

  • Groupвсі записи мають подібні name.
  • Matchті groups, у кого записи більше, ніж 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}}
])

о / р:

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

10

Відповідь, яку дав анхік, може бути дуже неефективною, якщо у вас є велика база даних, а ім'я атрибута присутнє лише в деяких документах.

Щоб підвищити ефективність, ви можете додати $ агресію до агрегації.

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

Перша група Запитайте групу відповідно до полів.

Потім ми перевіряємо унікальний ідентифікатор і підраховуємо його. Якщо кількість більший за 1, то поле дублюється у всій колекції, щоб ця річ була оброблена за допомогою $ match query.


1
не змогли зробити так, щоб ця робота працювала і для мене. Вниз голосування!
Матьє Г

Ця публікація стара, але може допомогти комусь. перевірте це, я перевірю, чи працює він у моїх місцевих. Навіть я натрапив на один блог щодо цього. Будь ласка, подивіться. compose.com/articles/finding-duplicate-documents-in-mongodb
Аман Shrivastava

Мені вдалося змусити його працювати - відредагував оновлення до підтвердженої робочої версії.
AL Strine
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.