MongoDB: ¿Cómo actualizar varios documentos con un solo comando?

144

Me sorprendió descubrir que el siguiente código de ejemplo solo actualiza un único documento:

> db.test.save({"_id":1, "foo":"bar"});
> db.test.save({"_id":2, "foo":"bar"});

> db.test.update({"foo":"bar"}, {"$set":{"test":"success!"}});

> db.test.find({"test":"success!"}).count();
1

Sé que puedo recorrer y seguir actualizando hasta que todos cambien, pero eso parece terriblemente ineficiente. ¿Hay una mejor manera?

Luke Dennis
fuente

Respuestas:

247

La actualización múltiple se agregó recientemente, por lo que solo está disponible en las versiones de desarrollo (1.1.3). Desde el shell, realiza una actualización múltiple pasando trueel cuarto argumento a update(), donde el tercer argumento es el argumento upsert:

db.test.update({foo: "bar"}, {$set: {test: "success!"}}, false, true);

Para las versiones de mongodb 2.2+, debe configurar la opción multi true para actualizar varios documentos a la vez.

db.test.update({foo: "bar"}, {$set: {test: "success!"}}, {multi: true})

Para las versiones de mongodb 3.2+ también puede usar un nuevo método updateMany()para actualizar varios documentos a la vez, sin la necesidad de una multiopción separada .

db.test.updateMany({foo: "bar"}, {$set: {test: "success!"}})
mdirolf
fuente
3
No estoy seguro de cuándo ocurrió este cambio, pero Mongodb v2.2.2 lo hace de manera un poco diferente. db.collection.update (<consulta>, <actualización>, <opciones>) donde options es un conjunto de pares de valores clave. Ver documentación: docs.mongodb.org/manual/applications/update
TechplexEngineer
3
¿Qué pasa si quiero establecer establecer diferentes valores para diferentes documentos? ¿Hay alguna forma elegante de hacer esto?
zach
Cómo hacerlo para oldvalue + "some string"
Mahesh K
34

A partir de la v3.3 Puede usar updateMany

db.collection.updateMany(
   <filter>,
   <update>,
   {
     upsert: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ]
   }
)

En v2.2, la función de actualización toma la siguiente forma:

 db.collection.update(
   <query>,
   <update>,
   { upsert: <boolean>, multi: <boolean> }
)

https://docs.mongodb.com/manual/reference/method/db.collection.update/

usuario602525
fuente
16

Para la versión Mongo> 2.2 , agregue un campo múltiple y configúrelo como verdadero

db.Collection.update({query}, 
                 {$set: {field1: "f1", field2: "f2"}},
                 {multi: true })
Kartik Singh
fuente
7

He creado una forma de hacer esto con una mejor interfaz.

  • db.collection.find({ ... }).update({ ... }) - actualización múltiple
  • db.collection.find({ ... }).replace({ ... }) - reemplazo individual
  • db.collection.find({ ... }).upsert({ ... }) - upsert simple
  • db.collection.find({ ... }).remove() - multi remove

También puede aplicar límite, omitir, ordenar a las actualizaciones y elimina encadenándolas de antemano.

Si estás interesado, echa un vistazo a Mongo-Hacker

Tyler Brock
fuente
1
TypeError: db.getCollection (...). Find (...). Update no es una función:?
Anthony
no funcionó db.userActivity.find({ 'appId' : 1234, 'status' : 1}).update({ $set: { 'status': 1 } }); 2017-06-05T17:47:10.038+0530 E QUERY [thread1] TypeError: db.userActivity.find(...).update is not a function :
Prakash Pandey
4

En el cliente MongoDB, escriba:

db.Collection.updateMany({}, $set: {field1: 'field1', field2: 'field2'})

Nuevo en la versión 3.2

Parámetros ::

{}:  select all records updated

Argumento de palabra clave multino tomado

Boseam
fuente
3

MongoDB encontrará solo un documento coincidente que coincida con los criterios de consulta cuando emita un comando de actualización, el documento que coincida primero se actualizará, incluso si hay más documentos que coincidan con los criterios serán ignorados.

para superar esto, podemos especificar la opción "MULTI" en su declaración de actualización, lo que significa actualizar todos esos documentos que coincidan con los criterios de consulta. busque todos los documnets en la colección y encuentre los que coincidan con los criterios y actualice:

db.test.update({"foo":"bar"},{"$set":{"test":"success!"}}, {multi:true} )
Yathish Manjunath
fuente
2

El siguiente comando puede actualizar múltiples registros de una colección

db.collection.update({}, 
{$set:{"field" : "value"}}, 
{ multi: true, upsert: false}
)
Sachintha Nayanajith
fuente
1

Tuve el mismo problema y encontré la solución, y funciona de maravilla

solo establezca la bandera multi en true de esta manera:

 db.Collection.update(
                {_id_receiver: id_receiver},
               {$set: {is_showed: true}},
                {multi: true}   /* --> multiple update */
            , function (err, updated) {...});

Espero que eso ayude :)

Amine_Dev
fuente
1

Para actualizar toda la colección,

db.getCollection('collection_name').update({},
{$set: {"field1" : "value1", "field2" : "value2", "field3" : "value3"}},
{multi: true })
Isuru Amarathunga
fuente
0

Puedes usar.`

        Model.update({
            'type': "newuser"
        }, {
            $set: {
                email: "[email protected]",
                phoneNumber:"0123456789"
            }
        }, {
            multi: true
        },
        function(err, result) {
            console.log(result);
            console.log(err);
        })  `
Jitendra
fuente
0

Todas las últimas versiones de mongodb updateMany () funcionan bien

db.getCollection('workers').updateMany({},{$set: {"assignedVehicleId" : "45680"}});
KARTHIKEYAN.A
fuente
-1

Gracias por compartir esto, utilicé con 2.6.7 y la siguiente consulta simplemente funcionó,

para todos los documentos:

db.screen.update({stat:"PRO"} , {$set : {stat:"pro"}}, {multi:true})

para un solo documento:

db.screen.update({stat:"PRO"} , {$set : {stat:"pro"}}, {multi:false})
Athar
fuente