Alternatywnym podejściem jest użycie aggregation framework
który ma lepszą wydajność niż map-reduce. Rozważmy następujący potok agregacji, który jako pierwszy etap potoku agregacji, $group
operator grupuje dokumenty według ID
i przechowuje w unique_ids
każde pole _id
wartość zgrupowanych rekordów przy użyciu $addToSet
operator. $sum
Operator akumulatora sumuje wartości przekazanych mu pól, w tym przypadku stałą 1 - w ten sposób zliczając ilość zgrupowanych rekordów do pola count. Drugi krok potoku $match
filtruje dokumenty o liczbie co najmniej 2, czyli duplikaty.
Po uzyskaniu wyniku z agregacji iterujesz kursor, aby usunąć pierwszy _id
w unique_ids
a następnie włóż resztę do tablicy, która zostanie później użyta do usunięcia duplikatów (minus jeden wpis):
cursor = db.coll.aggregate(
[
{"$group": {"_id": "$ID", "unique_ids": {"$addToSet": "$_id"}, "count": {"$sum": 1}}},
{"$match": {"count": { "$gte": 2 }}}
]
)
response = []
for doc in cursor:
del doc["unique_ids"][0]
for id in doc["unique_ids"]:
response.append(id)
coll.remove({"_id": {"$in": response}})