A resposta aceita é terrivelmente lenta em grandes coleções e não retorna o
_id
s dos registros duplicados. A agregação é muito mais rápida e pode retornar o
_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 }
]);
No primeiro estágio do pipeline de agregação, o $groupoperator agrega documentos pelo
name
campo e armazena em uniqueIds
cada _id
valor dos registros agrupados. O operador $sum soma os valores dos campos passados a ele, neste caso a constante 1
- contando assim o número de registros agrupados no count
campo. No segundo estágio do pipeline, usamos $matchpara filtrar documentos com um
count
de pelo menos 2, ou seja, duplicatas. Em seguida, classificamos primeiro as duplicatas mais frequentes e limitamos os resultados aos 10 primeiros.
Esta consulta produzirá até
$limit
registros com nomes duplicados, juntamente com seu _id
s. Por exemplo:{
"_id" : {
"name" : "Toothpick"
},
"uniqueIds" : [
"xzuzJd2qatfJCSvkN",
"9bpewBsKbrGBQexv4",
"fi3Gscg9M64BQdArv",
],
"count" : 3
},
{
"_id" : {
"name" : "Broom"
},
"uniqueIds" : [
"3vwny3YEj2qBsmmhA",
"gJeWGcuX6Wk69oFYD"
],
"count" : 2
}