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!"}})

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/


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не принят


3

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

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

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

2

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

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

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})
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.