MongoDB: Como atualizar vários documentos com um único comando?

144

Fiquei surpreso ao descobrir que o seguinte código de exemplo atualiza apenas um ú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

Eu sei que posso fazer um loop e continuar atualizando até que tudo mude, mas isso parece terrivelmente ineficiente. Existe uma maneira melhor?

Luke Dennis
fonte

Respostas:

247

A atualização múltipla foi adicionada recentemente, portanto, está disponível apenas nas versões de desenvolvimento (1.1.3). No shell, você faz uma atualização múltipla passando truecomo o quarto argumento para update(), onde o terceiro argumento é o argumento upsert:

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

Para versões do mongodb 2.2+, você precisa definir a opção multi true para atualizar vários documentos ao mesmo tempo.

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

Para versões do mongodb 3.2+, você também pode usar o novo método updateMany()para atualizar vários documentos de uma só vez, sem a necessidade de uma multiopção separada .

db.test.updateMany({foo: "bar"}, {$set: {test: "success!"}})
mdirolf
fonte
3
Não tenho certeza de quando essa alteração ocorreu, mas o Mongodb v2.2.2 faz isso de maneira um pouco diferente. db.collection.update (<query>, <update>, <options>) em que options é um conjunto de pares de valores-chave. Consulte a documentação: docs.mongodb.org/manual/applications/update
TechplexEngineer
3
e se eu quiser definir valores diferentes para documentos diferentes? existe uma maneira alegante de fazer isso?
Zach
Como fazê-lo para OldValue + "alguma string"
Mahesh K
34

A partir da v3.3 Você pode usar o updateMany

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

Na v2.2, a função de atualização assume o seguinte formato:

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

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

user602525
fonte
16

Para a versão Mongo> 2.2 , adicione um campo multi e defina-o como true

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

Eu criei uma maneira de fazer isso com uma interface melhor.

  • db.collection.find({ ... }).update({ ... }) - atualização múltipla
  • db.collection.find({ ... }).replace({ ... }) - substituição única
  • db.collection.find({ ... }).upsert({ ... }) - upsert único
  • db.collection.find({ ... }).remove() - remoção múltipla

Você também pode aplicar limite, pular, classificar e atualizar as atualizações, encadeando-as com antecedência.

Se você estiver interessado, confira o Mongo-Hacker

Tyler Brock
fonte
1
TypeError: db.getCollection (...). Find (...). Update não é uma função:?
Anthony
não funcionou 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

No cliente MongoDB, digite:

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

Novo na versão 3.2

Params ::

{}:  select all records updated

Argumento de palavra-chave multinão utilizado

Boseam
fonte
3

O MongoDB encontrará apenas um documento correspondente que corresponda aos critérios de consulta quando você estiver emitindo um comando de atualização, o documento que corresponder primeiro for atualizado, mesmo que haja mais documentos que correspondam aos critérios que serão ignorados.

para superar isso, podemos especificar a opção "MULTI" em sua declaração de atualização, o que significa atualizar todos os documentos que correspondem aos critérios de consulta. procure todos os documentos na coleção, encontrando aqueles que correspondem aos critérios e atualize:

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

O comando a seguir pode atualizar vários registros de uma coleção

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

Eu tive o mesmo problema e encontrei a solução, e funciona como um encanto

basta definir o sinalizador multi para true como este:

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

espero que ajude :)

Amine_Dev
fonte
1

Para atualizar a coleção inteira,

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

Você pode usar.`

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

Todas as versões mais recentes do mongodb updateMany () estão funcionando bem

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

Obrigado por compartilhar isso, eu usei com o 2.6.7 e a consulta a seguir funcionou,

para todos os documentos:

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

para documento único:

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