Uma abordagem alternativa é usar a
aggregation framework
que tem melhor desempenho do que map-reduce. Considere o seguinte pipeline de agregação que, como o primeiro estágio do pipeline de agregação, o $group
operador agrupa documentos pelo ID
campo e armazena no unique_ids
campo cada _id
valor dos registros agrupados usando o $addToSet
operador. O $sum
O operador acumulador soma os valores dos campos passados a ele, neste caso a constante 1 - contando assim o número de registros agrupados no campo de contagem. A outra etapa do pipeline $match
filtra documentos com uma contagem de pelo menos 2, ou seja, duplicados. Depois de obter o resultado da agregação, você itera o cursor para remover o primeiro
_id
no unique_ids
campo e, em seguida, insira o restante em uma matriz que será usada posteriormente para remover as duplicatas (menos uma entrada):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}})