Найти дубликаты записей в 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.
ОБНОВЛЕНИЕ ====== Работает каждый раз!
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