borrar duplicados mongodb

Hoy tenemos un pequeño snippet para borrar duplicados en MongoDB segun uno de los campos

Antes de la version 3 de MongoDB era bastante sencillo. Solo habia que crear un indice unico por el campo que queriamos que no tuviera duplicados con la opcion dropDups: true tal y como se puede ver en la documentacion. Este es el ejemplo:

db.collection.ensureIndex( { a: 1 }, { unique: true, dropDups: true } )

Pero si tienes la version 3 o superior la cosa cambia ya que tendras que ser tu el que haga un codigo que borre esos registros

Borrar duplicados en la version 3.0

Para borrar duplicados vamos a usar el aggregation framework

Este seria el codigo en NodeJs

var MongoClient = require('mongodb').MongoClient;

var url = 'mongodb://localhost:27017/mydb';
MongoClient.connect(url, function (err, db) {
    var mycol = db.collection('mycol');

    var duplicates = [];
    mycol.aggregate([
            
            {
                $match: {
                    myfield: {"$ne": ''} // myfield es el campo por el que queremos borrar los duplicados
                }
            },
            {
                $group: {
                    _id: {myfield: "$myfield"},
                    dups: {"$addToSet": "$_id"},
                    count: {"$sum": 1}
                }
            },
            {
                $match: {
                    count: {"$gt": 1}
                }
            }
        ], function (err, result) {
            if (err) {
                console.error(err);
                return db.close();
            }

            result.forEach(function (doc) {
                doc.dups.shift(); // Nos quedamos con el primer elemento
                doc.dups.forEach(function (dupId) {
                    duplicates.push(dupId);
                });
            });

            mycol.remove({_id: {$in: duplicates}}, function (err, result) {
                if (err) {
                    console.error(err);
                }

                db.close();
            });
        });

Y ya esta el trabajo hecho. Con unas pocas lineas podemos volver a tener la funcionalidad que ya no existe en las nuevas versiones de MongoDB

Las razones por las que MongoDB decidio quitar esta funcionalidad es porque al borrar los duplicados se quedaban con el primer documento que encontraba y borraba los demas, es decir, lo que hacemos nosotros en este codigo. Lo bueno es que con este codigo podrias quedarte con el documento que necesites (el ultimo insertado, el primero, el que tenga un campo especifico…)