Det accepterade svaret är fruktansvärt långsamt på stora samlingar och returnerar inte _id
s av dubblettposterna.
Aggregation är mycket snabbare och kan returnera _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 det första steget av aggregeringspipelinen aggregerar $groupoperator dokument med name
och lagrar i uniqueIds
varje _id
värdet för de grupperade posterna. Operatorn $sum lägger ihop värdena för fälten som skickas till den, i detta fall konstanten 1
- räknar därmed antalet grupperade poster i count
fältet.
I det andra steget av pipelinen använder vi $matchto filterdokument med en count
av minst 2, d.v.s. dubbletter.
Sedan sorterar vi de vanligaste dubbletterna först och begränsar resultaten till topp 10.
Den här frågan matar ut upp till $limit
poster med dubbletter av namn, tillsammans med deras _id
s. Till exempel:
{
"_id" : {
"name" : "Toothpick"
},
"uniqueIds" : [
"xzuzJd2qatfJCSvkN",
"9bpewBsKbrGBQexv4",
"fi3Gscg9M64BQdArv",
],
"count" : 3
},
{
"_id" : {
"name" : "Broom"
},
"uniqueIds" : [
"3vwny3YEj2qBsmmhA",
"gJeWGcuX6Wk69oFYD"
],
"count" : 2
}