Найти дубликаты записей в MongoDB

Как бы я найти дубликаты полей в коллекции монго.

Я хотел бы проверить, являются ли какие-либо из полей "name" дубликатами.

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

Большое спасибо!

11 ответов

Решение

Использовать агрегацию на 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", измените "$ name" на "$ column_name"

Вы можете найти 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" ] }

Другой вариант — использовать $sortByCountсцена.

      db.collection.aggregate([
  { $sortByCount: '$name' }
]

это сочетание $group& $sort

Ответ anhic может быть очень неэффективным, если у вас большая база данных, а имя атрибута присутствует только в некоторых документах.

Для повышения эффективности вы можете добавить $match к агрегации.

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

Первая группа Запрос группы в соответствии с полями.

Затем мы проверяем уникальный Id и подсчитываем его. Если count больше 1, тогда поле дублируется во всей коллекции, так что это должно быть обработано запросом $match.

вот как мы можем добиться этого в компасе mongoDB

ОБНОВЛЕНИЕ ====== Работает каждый раз!

      db.users.aggregate([
    // Group by the key and compute the number of documents that match the key
    {
        $group: {
            _id: "$username",  // or if you want to use multiple fields _id: { a: "$FirstName", b: "$LastName" }
            count: { $sum: 1 }
        }
    },
    // Filter group having more than 1 item, which means that at least 2 documents have the same key
    {
        $match: {
            count: { $gt: 1 }
        }
    }
])

==========

Эта агрегация также работала для меня...

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

Вы также можете попробовать $sortByCount

      db.collection.aggregate([
  { $sortByCount: '$username' }
]

Если вам нужно увидеть все повторяющиеся строки:

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

Иногда вам нужно найти дубликаты независимо от регистра, например, когда вы хотите создать индекс без учета регистра. В этом случае вы можете использовать этоaggregationтрубопровод

      db.collection.aggregate([
  {'$group': {'_id': {'$toLower': '$name'}, 'count': { '$sum': 1 }, 'duplicates': { '$push': '$$ROOT' } } },
  {'$match': { 'count': { '$gt': 1 } } 
]);

Объяснение:

  • groupкnameно сначала измените регистр на нижний регистр и переместите документы вduplicatesмножество.
  • matchте группы, в которых записи больше 1 (дубликаты).

Если кто-то ищет дубликаты с дополнительным предложением "$ и" where, например "and where someOtherField истинно"

      {
    $group: {
        _id: {
            name: "$name"
            someOtherField: "$someOtherField"
        },
        count: { $sum: 1 }
     }
},
{
    $match: {
        count: { $gte: 2 },
        "_id.someOtherField": true,
    }
},

Я очень долго искал эту нотацию, надеюсь, что смогу помочь кому-нибудь с той же проблемой

Поиск дубликатов в БД Compass Mongo с помощью $sortByCount
[скриншот]: https://stackru.com/images/a91601cf73b7c3da1b0c9d49a36cf7ad609ee02b.png

Другие вопросы по тегам