La réponse acceptée est terriblement lente sur les grandes collections et ne renvoie pas le _id
s des enregistrements en double.
L'agrégation est beaucoup plus rapide et peut renvoyer le _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 }
]);
Dans la première étape du pipeline d'agrégation, le $groupoperator agrège les documents par le name
champ et stocke dans uniqueIds
chaque _id
valeur des enregistrements groupés. L'opérateur $sum additionne les valeurs des champs qui lui sont passés, en l'occurrence la constante 1
- comptant ainsi le nombre d'enregistrements groupés dans le count
champ.
Dans la deuxième étape du pipeline, nous utilisons $matchpour filtrer les documents avec un count
d'au moins 2, c'est-à-dire des doublons.
Ensuite, nous trions d'abord les doublons les plus fréquents et limitons les résultats aux 10 premiers.
Cette requête affichera jusqu'à $limit
enregistrements avec des noms en double, ainsi que leur _id
s. Par exemple :
{
"_id" : {
"name" : "Toothpick"
},
"uniqueIds" : [
"xzuzJd2qatfJCSvkN",
"9bpewBsKbrGBQexv4",
"fi3Gscg9M64BQdArv",
],
"count" : 3
},
{
"_id" : {
"name" : "Broom"
},
"uniqueIds" : [
"3vwny3YEj2qBsmmhA",
"gJeWGcuX6Wk69oFYD"
],
"count" : 2
}