type tutorial los indexes index funcionan create consultas como avanzadas mongodb mapreduce

tutorial - Una forma rápida de encontrar duplicados en la columna indexada en mongodb



mongodb indexes tutorial (3)

La forma más fácil de hacerlo en una sola pasada es ordenar por md5 y luego procesarlo adecuadamente.

Algo como:

var previous_md5; db.files.find( {"md5" : {$exists:true} }, {"md5" : 1} ).sort( { "md5" : 1} ).forEach( function(current) { if(current.md5 == previous_md5){ db.duplicates.update( {"_id" : current.md5}, { "$inc" : {count:1} }, true); } previous_md5 = current.md5; });

Ese pequeño script ordena las entradas md5 y las recorre en orden. Si se repite un md5, serán "seguidos" después de la clasificación. Así que solo mantenemos un puntero a previous_md5 y lo comparamos current.md5 . Si encontramos un duplicado, lo coloco en la colección de duplicates (y uso $ inc para contar el número de duplicados).

Este script significa que solo tiene que recorrer el conjunto de datos principal una vez. Luego puede recorrer la colección de duplicates y realizar la limpieza.

Tengo una colección de md5 en mongodb. Me gustaría encontrar todos los duplicados. La columna md5 está indexada. ¿Conoces alguna forma rápida de hacer eso usando el mapa reducir. ¿O debería simplemente iterar sobre todos los registros y verificar los duplicados manualmente?

Mi enfoque actual utilizando el mapa reduce las iteraciones sobre la colección casi dos veces (asumiendo que hay una cantidad muy pequeña de duplicados):

res = db.files.mapReduce( function () { emit(this.md5, 1); }, function (key, vals) { return Array.sum(vals); } ) db[res.result].find({value: {$gte:1}}).forEach( function (obj) { out.duplicates.insert(obj) });


Personalmente, encontré que la respuesta aceptada en las grandes bases de datos (1 TB y más) es terriblemente lenta. La agregación es mucho más rápida. El ejemplo está abajo:

db.places.aggregate( { $group : {_id : "$extra_info.id", total : { $sum : 1 } } }, { $match : { total : { $gte : 2 } } }, { $sort : {total : -1} }, { $limit : 5 } );

Busca documentos cuyo extra_info.id se usa dos veces o más, ordena los resultados en orden descendente de un campo determinado e imprime los primeros 5 valores del mismo.


Puede hacer un grupo por ese campo y luego consultar para obtener el duplicado (tener un conteo> 1). http://www.mongodb.org/display/DOCS/Aggregation#Aggregation-Group

Aunque, lo más rápido podría ser simplemente hacer una consulta que solo devuelva ese campo y luego hacer la agregación en el cliente. Group / Map-Reduce necesita proporcionar acceso a todo el documento, que es mucho más costoso que simplemente proporcionar los datos del índice (que ahora se trata en 1.7.3+).

Si este es un problema general que necesita ejecutar periódicamente, es posible que desee mantener una colección que sea solo {md5: value, count: value} para que pueda omitir la agregación, y será extremadamente rápida cuando necesite eliminar los duplicados .