Saltar al contenido

Encuentre todos los documentos duplicados en una colección MongoDB por un key campo

Nuestro equipo de redactores ha estado mucho tiempo buscando para darle resolución a tus interrogantes, te ofrecemos la resolución por eso deseamos resultarte de mucha apoyo.

Solución:

La respuesta aceptada es terriblemente lenta en colecciones grandes y no devuelve el _ids de los registros duplicados.

La agregación es mucho más rápida y puede devolver el _ids:

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 
]);

En la primera etapa de la canalización de agregación, el operador $group agrega documentos por el name campo y tiendas en uniqueIds cada _id valor de los registros agrupados. El operador $sum suma los valores de los campos que se le pasan, en este caso la constante 1 – contando así el número de registros agrupados en el count campo.

En la segunda etapa de la canalización, usamos $match para filtrar documentos con un count de al menos 2, es decir, duplicados.

Luego, ordenamos primero los duplicados más frecuentes y limitamos los resultados a los 10 principales.

Esta consulta generará hasta $limit registros con nombres duplicados, junto con sus _ids. Por ejemplo:


  "_id" : 
    "name" : "Toothpick"
,
  "uniqueIds" : [
    "xzuzJd2qatfJCSvkN",
    "9bpewBsKbrGBQexv4",
    "fi3Gscg9M64BQdArv",
  ],
  "count" : 3
,

  "_id" : 
    "name" : "Broom"
  ,
  "uniqueIds" : [
    "3vwny3YEj2qBsmmhA",
    "gJeWGcuX6Wk69oFYD"
  ],
  "count" : 2

Nota: esta solución es la más fácil de entender, pero no la mejor.

Puedes usar mapReduce para saber cuántas veces un documento contiene un determinado campo:

var map = function()
   if(this.name) 
        emit(this.name, 1);
   


var reduce = function(key, values)
    return Array.sum(values);


var res = db.collection.mapReduce(map, reduce, out: inline : 1);
db[res.result].find(value: $gt: 1).sort(value: -1);

Para obtener una solución genérica de Mongo, consulte la receta del libro de cocina de MongoDB para encontrar duplicados usando group. Tenga en cuenta que la agregación es más rápida y poderosa porque puede devolver el _ids de los registros duplicados.

Para pymongo, la respuesta aceptada (usando mapReduce) no es tan eficiente. En su lugar, podemos usar el método de grupo:

$connection = 'mongodb://localhost:27017';
$con        = new Mongo($connection); // mongo db connection

$db         = $con->test; // database 
$collection = $db->prb; // table

$keys       = array("name" => 1); Select name field, group by it

// set intial values
$initial    = array("count" => 0);

// JavaScript function to perform
$reduce     = "function (obj, prev)  prev.count++; ";

$g          = $collection->group($keys, $initial, $reduce);

echo "
";
print_r($g);

La salida será esta:

Array
(
    [retval] => Array
        (
            [0] => Array
                (
                    [name] => 
                    [count] => 1
                )

            [1] => Array
                (
                    [name] => MongoDB
                    [count] => 2
                )

        )

    [count] => 3
    [keys] => 2
    [ok] => 1
)

La consulta SQL equivalente sería: SELECT name, COUNT(name) FROM prb GROUP BY name. Tenga en cuenta que todavía tenemos que filtrar los elementos con un recuento de 0 de la array. Nuevamente, consulte la receta del libro de cocina de MongoDB para encontrar duplicados usando group para la solución canónica usando group.

Comentarios y valoraciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *