MongoDB: как обновить несколько документов с помощью одной команды?

154

Я был удивлен, обнаружив, что следующий пример кода обновляет только один документ:

> 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

Я знаю, что могу прокручивать и продолжать обновлять, пока они все не изменятся, но это кажется ужасно неэффективным. Есть ли способ лучше?

Люк Деннис
источник

Ответы:

258

Множественное обновление было добавлено недавно, поэтому доступно только в разрабатываемых версиях (1.1.3). Из оболочки вы выполняете многократное обновление, передавая trueв качестве четвертого аргумента в update(), где третий аргумент является аргументом upsert:

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

Для версий mongodb 2.2+ вам необходимо установить опцию multi true для одновременного обновления нескольких документов.

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

Для версий mongodb 3.2+ вы также можете использовать новый метод updateMany()для одновременного обновления нескольких документов без необходимости отдельной multiопции.

db.test.updateMany({foo: "bar"}, {$set: {test: "success!"}})
mdirolf
источник
3
Я не уверен, когда произошло это изменение, но Mongodb v2.2.2 делает это немного иначе. db.collection.update (<query>, <update>, <options>), где options - это набор пар ключ-значение. См. Документацию: docs.mongodb.org/manual/applications/update
TechplexEngineer
3
что, если я хочу установить разные значения для другого документа? есть ли элегантный способ сделать это?
zach
Как это сделать для oldvalue + "some string"
Махеш К.
34

Начиная с v3.3 вы можете использовать updateMany

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

В версии 2.2 функция обновления принимает следующую форму:

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

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

user602525
источник
16

Для версии Mongo> 2.2 добавьте поле multi и установите для него значение true

db.Collection.update({query}, 
                 {$set: {field1: "f1", field2: "f2"}},
                 {multi: true })
Картик Сингх
источник
7

Я создал способ сделать это с помощью лучшего интерфейса.

  • db.collection.find({ ... }).update({ ... }) - мульти обновление
  • db.collection.find({ ... }).replace({ ... }) - разовая замена
  • db.collection.find({ ... }).upsert({ ... }) - одиночный апсерт
  • db.collection.find({ ... }).remove() - множественное удаление

Вы также можете применить ограничение, пропустить, отсортировать обновления и удалить, предварительно связав их.

Если вам интересно, посмотрите Mongo-Hacker

Тайлер Брок
источник
1
TypeError: db.getCollection (...). Find (...). Update не является функцией:?
Энтони
не сработало 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

В клиенте MongoDB введите:

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

Новое в версии 3.2

Params ::

{}:  select all records updated

Аргумент ключевого слова multiне принят

Boseam
источник
3

MongoDB найдет только один соответствующий документ, который соответствует критериям запроса, когда вы вводите команду обновления, какой бы документ ни совпадал первым, будет обновлен, даже если есть другие документы, соответствующие критериям, будут проигнорированы.

поэтому, чтобы преодолеть это, мы можем указать опцию «MULTI» в вашем операторе обновления, что означает обновление всех тех документов, которые соответствуют критериям запроса. сканировать все документы в коллекции, находя те, которые соответствуют критериям, и обновлять:

db.test.update({"foo":"bar"},{"$set":{"test":"success!"}}, {multi:true} )
Ятиш Манджунатх
источник
2

Следующая команда может обновить несколько записей коллекции

db.collection.update({}, 
{$set:{"field" : "value"}}, 
{ multi: true, upsert: false}
)
Sachintha Nayanajith
источник
1

У меня была такая же проблема, и я нашел решение, и оно работает как шарм

просто установите для флага multi значение true, вот так:

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

Надеюсь, это поможет :)

Амин_Дев
источник
1

Чтобы обновить всю коллекцию,

db.getCollection('collection_name').update({},
{$set: {"field1" : "value1", "field2" : "value2", "field3" : "value3"}},
{multi: true })
Исуру Амаратунга
источник
0

Вы можете использовать.

        Model.update({
            'type': "newuser"
        }, {
            $set: {
                email: "abc@gmail.com",
                phoneNumber:"0123456789"
            }
        }, {
            multi: true
        },
        function(err, result) {
            console.log(result);
            console.log(err);
        })  `
Джитендра
источник
0

Все последние версии mongodb updateMany () работают нормально

db.getCollection('workers').updateMany({},{$set: {"assignedVehicleId" : "45680"}});
КАРТИКЕЯН А.
источник
-1

Спасибо, что поделились этим, я использовал 2.6.7, и следующий запрос просто работал,

для всех документов:

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

для одного документа:

db.screen.update({stat:"PRO"} , {$set : {stat:"pro"}}, {multi:false})
Атар
источник