MongoDB: come aggiornare più documenti con un singolo comando?

Sono stato sorpreso di scoprire che il seguente codice di esempio aggiorna solo un singolo 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 

So che posso eseguire il ciclo di aggiornamento e aggiornamento finché non saranno tutti modificati, ma ciò sembra terribilmente inefficiente. C’è un modo migliore?

Il multi-aggiornamento è stato aggiunto di recente, quindi è disponibile solo nelle versioni di sviluppo (1.1.3). Dalla shell si esegue un aggiornamento multiplo passando true come quarto argomento di update() , dove il terzo argomento è l’argomento upsert:

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

Per le versioni di mongodb 2.2+ è necessario impostare l’opzione multi true per aggiornare più documenti contemporaneamente.

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

Per le versioni di mongodb 3.2+ è anche ansible utilizzare il nuovo metodo updateMany() per aggiornare più documenti contemporaneamente, senza la necessità di un’opzione multi separata.

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

AGGIORNAMENTO a partire dalla V2.2, la funzione di aggiornamento assume la forma seguente:

  db.collection.update( , , { upsert: , multi:  } ) 

La risposta selezionata non si applica più.

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

Per la versione di Mongo> 2.2 , aggiungi un campo multi e impostalo su true

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

Ho creato un modo per farlo con un’interfaccia migliore.

  • db.collection.find({ ... }).update({ ... }) – multi update
  • db.collection.find({ ... }).replace({ ... }) – sostituzione singola
  • db.collection.find({ ... }).upsert({ ... }) – single upsert
  • db.collection.find({ ... }).remove() – multi remove

È inoltre ansible applicare il limite, saltare, ordinare gli aggiornamenti e rimuoverli concatenandoli in anticipo.

Se sei interessato, dai un’occhiata a Mongo-Hacker

MongoDB troverà un solo documento di corrispondenza che corrisponde ai criteri della query quando si sta eseguendo un comando di aggiornamento, a seconda di quale documento si verifica per primo viene aggiornato, anche se ci sono più documenti che corrispondono ai criteri verranno ignorati.

quindi per ovviare a questo possiamo specificare l’opzione “MULTI” nella tua dichiarazione di aggiornamento, ovvero aggiornare tutti quei documnet che corrispondono ai criteri della query. cerca tutti i documnet nella collezione trovando quelli che corrispondono ai criteri e aggiorna:

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

Nel client MongoDB, digitare:

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

Novità nella versione 3.2

Parametri ::

 {}: select all records updated 

Argomento della parola chiave multi non utilizzato

Ho avuto lo stesso problema, e ho trovato la soluzione, e funziona come un fascino

basta impostare il flag multi su true in questo modo:

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

Spero che aiuti 🙂

Puoi usare

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

Tutte le ultime versioni di mongodb updateMany () funzionano correttamente

 db.getCollection('workers').updateMany({},{$set: {"assignedVehicleId" : "45680"}}); 

Per le versioni di mongodb 3.2+ è ansible utilizzare il metodo updateMany () per aggiornare più documenti

 db.documentName.updateMany({"conditionFiledName":"value"}, {$set: {fieldName1: value1,fieldName2: value2}}) 

Grazie per aver condiviso questo, ho usato con 2.6.7 e la seguente query ha funzionato,

per tutti i documenti:

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

per singolo documento:

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