2011-07-06 19 views
38

¿Cómo implementar algo similar a db.collection.find().limit(10) pero al actualizar documentos?Cómo limitar el número de documentos de actualización en mongodb

Ahora estoy usando algo muy malo como obtener documentos con db.collection.find().limit() y luego actualizarlos.

En general, quiero devolver una determinada cantidad de registros y cambiar un campo en cada uno de ellos.

Gracias.

+5

Para su información: Hay un billete abierto para esto (desde 2010, v1.6.0) https://jira.mongodb.org/browse/SERVER-1599 pero no está prevista para su lanzamiento en cualquier momento pronto. – zamnuts

Respuesta

10

Lamentablemente, la solución alternativa que tiene es la única manera de hacerlo AFAIK. Hay una bandera booleana multi que actualizará todas las coincidencias (cuando true) o actualice la primera coincidencia (cuando false).

-6

No estoy seguro de cuál es el propósito de aplicar un límite a las actualizaciones (ni siquiera es posible en SQL). Como lobster worte: la actualización funciona solo en un documento o en todos los documentos que coinciden con los criterios de actualización. Por lo tanto, debe ajustar los criterios según sus necesidades o actualizar uno por uno según una consulta anterior.

+2

probé ambos enfoques en mis datos y find() all y luego update() funciona mucho más rápido que find_and_modify(). parece que esta es una forma de hacerlo. – awsum

+12

Eso en realidad no es cierto, por supuesto puede agregar un límite a una actualización en SQL. Ejemplo: "ACTUALIZAR tabla SET x = 1 WHERE x = 0 LIMIT 10". –

27

Se puede utilizar:

db.collection.find().limit(NUMBER_OF_ITEMS_YOU_WANT_TO_UPDATE).forEach(
    function (e) { 
     e.fieldToChange = "blah"; 
     .... 
     db.collection.save(e); 
    } 
); 

(Créditos para el código forEach: MongoDB: Updating documents using data from the same document)

Lo que esto hará es sólo cambiar el número de entradas que se especifiquen. Así que si usted quiere añadir un campo llamado "Newfield" con un valor de 1 a sólo la mitad de las entradas dentro de "colección", por ejemplo, se puede poner en

db.collection.find().limit(db.collection.count()/2).forEach(
    function (e) { 
     e.newField = 1; 
     db.collection.save(e); 
    } 
); 

Si a continuación desea hacer la otra mitad también tener "Newfield" pero con el valor 2, se puede hacer una actualización con la condición de que no existe Newfield:

db.collection.update({ newField : { $exists : false } }, { $set : { newField : 2 } }, {multi : true}); 
+0

Agradable, incluso funciona en el caparazón de Mongo –

1

Como afirma la respuesta aún no existe una manera de limitar el número de documentos para actualizar (o eliminar) a un valor> 1. Una solución para usar algo como:

db.collection.find(<condition>).limit(<limit>).forEach(function(doc){db.collection.update({_id:doc._id},{<your update>})}) 
6

Las soluciones que iteran sobre todos los objetos y luego las actualizan individualmente son muy lentas.

Recuperarlos todos y actualizar simultáneamente utilizando $in es más eficiente.

ids = People.where(firstname: 'Pablo').limit(10000).only(:_id).to_a.map(&:id) 
People.in(_id: ids).update_all(lastname: 'Cantero') 

La consulta está escrita usando Mongoid, pero también se puede reescribir fácilmente en Mongo Shell.

3

El uso de forEach para actualizar individualmente cada documento es lento. Puede actualizar los documentos en masa utilizando

ids = db.collection.find(<condition>).limit(<limit>).map(
    function(doc) { 
     return doc._id; 
    } 
); 
db.collection.updateMany({_id: {$in: ids}}, <update>}) 
Cuestiones relacionadas