Приетият отговор е ужасно бавен при големи колекции и не връща _id
s на дублираните записи.
Агрегацията е много по-бърза и може да върне _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 }
]);
В първия етап от конвейера за агрегиране, $groupoperator обобщава документи по name
поле и съхранява в uniqueIds
всеки _id
стойност на групираните записи. Операторът $sum събира стойностите на предадените му полета, в този случай константата 1
- като по този начин броят на групираните записи в count
поле.
Във втория етап от конвейера използваме $match за филтриране на документи с count
от поне 2, т.е. дубликати.
След това първо сортираме най-често срещаните дубликати и ограничаваме резултатите до първите 10.
Тази заявка ще изведе до $limit
записи с дублиращи се имена, заедно с техния _id
с. Например:
{
"_id" : {
"name" : "Toothpick"
},
"uniqueIds" : [
"xzuzJd2qatfJCSvkN",
"9bpewBsKbrGBQexv4",
"fi3Gscg9M64BQdArv",
],
"count" : 3
},
{
"_id" : {
"name" : "Broom"
},
"uniqueIds" : [
"3vwny3YEj2qBsmmhA",
"gJeWGcuX6Wk69oFYD"
],
"count" : 2
}