MongoDB: Jak zaktualizować wiele dokumentów za pomocą jednego polecenia?


145

Zaskoczyło mnie, że poniższy przykładowy kod aktualizuje tylko jeden dokument:

> 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

Wiem, że mogę przeglądać i aktualizować, dopóki wszystkie nie zostaną zmienione, ale wydaje się to strasznie nieefektywne. Czy jest lepszy sposób?

Odpowiedzi:


247

Ostatnio dodano wiele aktualizacji, więc jest dostępna tylko w wersjach rozwojowych (1.1.3). Z powłoki wykonujesz aktualizację wielokrotną, przekazując truejako czwarty argument do update(), gdzie trzeci argument jest argumentem upsert:

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

W przypadku wersji mongodb 2.2+ musisz ustawić opcję multi true, aby aktualizować wiele dokumentów naraz.

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

W przypadku wersji mongodb 3.2+ możesz również użyć nowej metody updateMany()do aktualizacji wielu dokumentów jednocześnie, bez potrzeby oddzielnej multiopcji.

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

3
Nie jestem pewien, kiedy nastąpiła ta zmiana, ale Mongodb v2.2.2 robi to trochę inaczej. db.collection.update (<query>, <update>, <options>), gdzie opcje to zestaw par klucz-wartość. Zobacz dokumentację: docs.mongodb.org/manual/applications/update
TechplexEngineer

3
co jeśli chcę ustawić różne wartości dla innego dokumentu? czy jest na to uczciwy sposób?
zach

Jak to zrobić dla oldvalue + "jakiś ciąg"
Mahesh K

34

Począwszy od wersji 3.3 możesz użyć updateMany

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

W wersji 2.2 funkcja aktualizacji ma następującą postać:

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

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


16

W przypadku wersji Mongo> 2.2 dodaj pole multi i ustaw je na true

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

7

Stworzyłem sposób, aby to zrobić za pomocą lepszego interfejsu.

  • db.collection.find({ ... }).update({ ... }) - wielokrotna aktualizacja
  • db.collection.find({ ... }).replace({ ... }) - pojedyncza wymiana
  • db.collection.find({ ... }).upsert({ ... }) - pojedynczy wzrost
  • db.collection.find({ ... }).remove() - usuwanie wielu

Możesz także zastosować ograniczanie, pomijać, sortować aktualizacje i usuwać, łącząc je wcześniej.

Jeśli jesteś zainteresowany, sprawdź Mongo-Hacker


1
TypeError: db.getCollection (...). Find (...). Update nie jest funkcją:?
Anthony

nie działało 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

W kliencie MongoDB wpisz:

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

Nowość w wersji 3.2

Parametry:

{}:  select all records updated

Argument słowa kluczowego multinie jest zajęty


3

MongoDB znajdzie tylko jeden pasujący dokument, który spełnia kryteria zapytania podczas wydawania polecenia aktualizacji, niezależnie od tego, który dokument pasuje jako pierwszy, zostanie zaktualizowany, nawet jeśli istnieje więcej dokumentów spełniających kryteria, zostanie zignorowany.

aby temu zaradzić, możemy określić opcję „MULTI” w instrukcji aktualizacji, co oznacza aktualizację wszystkich zestawów dokumentów, które spełniają kryteria zapytania. przeszukaj wszystkie zestawy dokumentów w kolekcji, znajdując te, które spełniają kryteria i zaktualizuj:

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

2

Następujące polecenie może zaktualizować wiele rekordów w kolekcji

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

1

Miałem ten sam problem i znalazłem rozwiązanie, które działa jak urok

po prostu ustaw flagę multi na true w ten sposób:

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

Mam nadzieję że to pomogło :)


1

Aby zaktualizować całą kolekcję,

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

0

Możesz użyć. "

        Model.update({
            'type': "newuser"
        }, {
            $set: {
                email: "abc@gmail.com",
                phoneNumber:"0123456789"
            }
        }, {
            multi: true
        },
        function(err, result) {
            console.log(result);
            console.log(err);
        })  `

0

Wszystkie najnowsze wersje mongodb updateMany () działają poprawnie

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

-1

Dzięki za udostępnienie tego, użyłem z 2.6.7 i następujące zapytanie właśnie działało,

dla wszystkich dokumentów:

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

dla pojedynczego dokumentu:

db.screen.update({stat:"PRO"} , {$set : {stat:"pro"}}, {multi:false})
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.