2010-11-10 24 views
37

Tengo una colección con 9 millones de registros. Actualmente estoy usando el siguiente script para actualizar toda la colección:MongoDB: ¿Cuál es la forma más rápida de actualizar todos los registros en una colección?

simple_update.js

db.mydata.find().forEach(function(data) { 
    db.mydata.update({_id:data._id},{$set:{pid:(2571 - data.Y + (data.X * 2572))}}); 
}); 

Esto se ejecuta desde la línea de comandos de la siguiente manera:

mongo my_test simple_update.js 

Así que todo lo que soy hacer es agregar un nuevo campo pid basado en un simple cálculo.

¿Hay una manera más rápida? Esto toma una cantidad significativa de tiempo.

Respuesta

27

Hay dos cosas que usted puede hacer.

  1. Envíe una actualización con el indicador 'multi' configurado en true.
  2. Almacena la función del lado del servidor e intenta usar server-side code execution.

Ese vínculo también contiene los siguientes consejos:

Ésta es una buena técnica para realizar el trabajo administrativo por lotes. Ejecute mongo en el servidor, conectándose a través de la interfaz localhost. La conexión es entonces muy rápida y de baja latencia. Esto es más amigable que db.eval() ya que db.eval() bloquea otras operaciones.

Este es probablemente el más rápido que obtendrá. Debe darse cuenta de que la emisión de actualizaciones de 9M en un solo servidor va a ser una operación pesada. Digamos que puedes obtener 3k actualizaciones/segundo, todavía estás hablando de correr durante casi una hora.

Y eso no es realmente un "problema de mongo", eso va a ser una limitación de hardware.

+0

Así que tienen múltiples instancias (esclavo/maestro) que sea más rápido? – mattjvincent

+0

Master/Slave no mejorará su tiempo de escritura. Mongo solo tiene un hilo de escritura y, por lo general, está limitado por el rendimiento del disco cuando realiza una actualización masiva como esta. Las "instancias múltiples" que necesita son sharding. Con la fragmentación, tendrá dos máquinas con dos discos separados y obtendrá casi el doble del rendimiento de escritura. Sin embargo, de nuevo, mire su hardware y compárelo con su rendimiento esperado. –

+0

Ok. Entiendo que. ¿Qué tal leer? ¿Es la fragmentación una forma de acelerar la lectura o la consulta también? – mattjvincent

0

No estoy seguro si será más rápido pero podría hacer una actualización múltiple. Simplemente diga update where _id > 0 (esto será cierto para cada objeto) y luego establezca el indicador 'multi' en verdadero y debería hacer lo mismo sin tener que iterar a través de toda la colección.

mira esto: MongoDB - Server Side Code Execution

18

estoy usando los: db.collection.update method

// db.collection.update(criteria, objNew, upsert, multi) // --> for reference 
db.collection.update({ "_id" : { $exists : true } }, objNew, upsert, true); 
+6

También puede usar {} (Objeto BSSON vacío) para el primer argumento. Usar null arrojará un error. Esta es una incoherencia en la API, ya que otros métodos aceptan nulo como criterio de búsqueda (y lo interpretan como "coinciden con cualquiera"), por ejemplo, las funciones find y findOne. –

Cuestiones relacionadas