Det accepterede svar er frygtelig langsomt på store samlinger og returnerer ikke _id
s af dubletposterne.
Aggregation er meget hurtigere og kan returnere _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 }
]);
I den første fase af aggregeringspipelinen samler $groupoperator dokumenter efter name
felt og gemmer i uniqueIds
hver _id
værdien af de grupperede poster. Operatoren $sum summerer værdierne af de felter, der sendes til den, i dette tilfælde konstanten 1
- derved tæller antallet af grupperede poster ind i count
felt.
I anden fase af pipelinen bruger vi $matchto filtrere dokumenter med en count
på mindst 2, dvs. dubletter.
Derefter sorterer vi de hyppigste dubletter først og begrænser resultaterne til top 10.
Denne forespørgsel udsender op til $limit
poster med duplikerede navne sammen med deres _id
s. For eksempel:
{
"_id" : {
"name" : "Toothpick"
},
"uniqueIds" : [
"xzuzJd2qatfJCSvkN",
"9bpewBsKbrGBQexv4",
"fi3Gscg9M64BQdArv",
],
"count" : 3
},
{
"_id" : {
"name" : "Broom"
},
"uniqueIds" : [
"3vwny3YEj2qBsmmhA",
"gJeWGcuX6Wk69oFYD"
],
"count" : 2
}