2012-02-17 228 views
5

Tengo una gran colección (~ 2.7 millones de documentos) en mongodb, y hay muchos duplicados. Intenté ejecutar ensureIndex({id:1}, {unique:true, dropDups:true}) en la colección. Mongo se aleja un poco antes de decidir too many dups on index build with dropDups=true.¿Cómo puedo eliminar duplicados en MongoDb?

¿Cómo puedo agregar el índice y deshacerme de los duplicados? O al revés, ¿cuál es la mejor manera de eliminar algunos dups para que mongo pueda construir con éxito el índice?

Para obtener puntos de bonificación, ¿por qué hay un límite en el número de dups que se pueden eliminar?

+0

Como opción: ejecute un mapa/reduzca que cuenta las ocurrencias para cada 'id'. A continuación, recorra este conjunto de resultados y para cada 'id' con duplicados, elimine todos los registros, pero primero. –

Respuesta

5

Para obtener puntos de bonificación, ¿por qué hay un límite en el número de dups que se pueden eliminar?

Es probable que MongoDB haga esto para defenderse. Si tiene dropDups en el campo incorrecto, puede manguear todo el conjunto de datos y bloquear el DB con operaciones de eliminación (que son "tan costosas" como las escrituras).

¿Cómo puedo agregar el índice y deshacerme de los duplicados?

Así que la primera pregunta es ¿por qué está creando un índice único en el campo id?

MongoDB crea un campo predeterminado _id que es automáticamente único y indexado. De forma predeterminada, MongoDB rellena el _id con un ObjectId; sin embargo, puede anularlo con el valor que desee. Entonces, si tiene un conjunto listo de valores de ID, puede usar esos.

Si no puede volver a importar los valores, cópielos en una nueva colección al cambiar id en _id. A continuación, puede soltar la colección anterior y cambiarle el nombre a la nueva. (nota de que obtendrá un montón de "errores de clave duplicados", asegurarse de que sus capturas de código y los ignora)

+2

¡Requiere edición! Debido a cambios en MongoDB> = 3. * –

3

me encontré con esta cuestión al tratar de encontrar una solución para los "demasiados dups" problema (sin volver a crear la colección de la fuente). La forma en que finalmente no es mediante la creación de una nueva colección c2, añadiendo un índice único en el campo (s) necesario (únicamente para acelerar propósito) y luego haciendo upsert:

db.c1.find().forEach(function(x){db.c2.update({field1:x.field1, field2:x.field2}, x, {upsert:true})}) 

donde las combinaciones de field1 y field2 debe ser único. Entonces uno solo puede soltar la colección inicial c1 y renombrar la nueva. Esta solución, como se muestra, puede funcionar para uno o múltiples campos.

Cuestiones relacionadas