La risposta accettata è terribilmente lenta su raccolte di grandi dimensioni e non restituisce il _id
s dei record duplicati.
L'aggregazione è molto più veloce e può restituire il _id
s:
db.collection.aggregate([
{ $group: {
_id: { name: "$name" }, // replace `name` here twice
uniqueIds: { $addToSet: "$_id" },
count: { $sum: 1 }
} },
{ $match: {
count: { $gte: 2 }
} },
{ $sort : { count : -1} },
{ $limit : 10 }
]);
Nella prima fase della pipeline di aggregazione, $groupoperator aggrega i documenti in base al name
campo e memorizza in uniqueIds
ogni _id
valore dei record raggruppati.L'operatore $sum somma i valori dei campi passatigli, in questo caso la costante 1
- contando così il numero di record raggruppati nel count
campo.
Nella seconda fase della pipeline, utilizziamo $match per filtrare i documenti con un count
di almeno 2, ovvero duplicati.
Quindi, ordiniamo per primi i duplicati più frequenti e limitiamo i risultati ai primi 10.
Questa query produrrà fino a $limit
record con nomi duplicati, insieme al loro _id
S. Ad esempio:
{
"_id" : {
"name" : "Toothpick"
},
"uniqueIds" : [
"xzuzJd2qatfJCSvkN",
"9bpewBsKbrGBQexv4",
"fi3Gscg9M64BQdArv",
],
"count" : 3
},
{
"_id" : {
"name" : "Broom"
},
"uniqueIds" : [
"3vwny3YEj2qBsmmhA",
"gJeWGcuX6Wk69oFYD"
],
"count" : 2
}