MongoDB: Как обновить несколько документов с помощью одной команды?
Я с удивлением обнаружил, что следующий примерный код обновляет только один документ:
> 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
Я знаю, что могу перебирать и обновлять, пока они не будут изменены, но это кажется ужасно неэффективным. Есть ли лучший способ?
Ответы
Ответ 1
Недавно было добавлено несколько обновлений, поэтому доступно только в релизах разработки (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!"}})
Ответ 2
Начиная с версии 3.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/
Ответ 3
Для Mongo version > 2.2 добавьте поле multi и установите его в true
db.Collection.update({query},
{$set: {field1: "f1", field2: "f2"}},
{multi: true })
Ответ 4
Я создал способ сделать это с помощью лучшего интерфейса.
-
db.collection.find({ ... }).update({ ... })
- многократное обновление
-
db.collection.find({ ... }).replace({ ... })
- единственная замена
-
db.collection.find({ ... }).upsert({ ... })
- single upsert
-
db.collection.find({ ... }).remove()
- multi remove
Вы также можете применять лимит, пропускать, сортировать обновления и удалять, предварительно связав их.
Если вам интересно, посмотрите Mongo-Hacker
Ответ 5
В клиенте MongoDB введите:
db.Collection.updateMany({}, $set: {field1: 'field1', field2: 'field2'})
Новое в версии 3.2
Params::
{}: select all records updated
Аргумент ключевого слова multi
не принят
Ответ 6
MongoDB найдет только один соответствующий документ, который соответствует критериям запроса при выдаче команды обновления, в зависимости от того, какой документ совпадает с первым, будет обновляться, даже если есть больше документов, которые соответствуют критериям, будут проигнорированы.
поэтому, чтобы преодолеть это, мы можем указать опцию "MULTI" в вашем заявлении о обновлении, то есть обновить все эти documnets, которые соответствуют критериям запроса. сканирование всех документов в коллекции, поиск которых соответствует критериям и обновлению:
db.test.update({"foo":"bar"},{"$set":{"test":"success!"}}, {multi:true} )
Ответ 7
У меня была та же проблема, и я нашел решение, и оно работает как шарм
просто установите флаг multi в true следующим образом:
db.Collection.update(
{_id_receiver: id_receiver},
{$set: {is_showed: true}},
{multi: true} /* --> multiple update */
, function (err, updated) {...});
Надеюсь, что это поможет:)
Ответ 8
Вы можете использовать.
Model.update({
'type': "newuser"
}, {
$set: {
email: "[email protected]",
phoneNumber:"0123456789"
}
}, {
multi: true
},
function(err, result) {
console.log(result);
console.log(err);
}) `
Ответ 9
Все последние версии mongodb updateMany() работают отлично
db.getCollection('workers').updateMany({},{$set: {"assignedVehicleId" : "45680"}});
Ответ 10
Спасибо, что поделились этим, я использовал с 2.6.7 и следующий запрос просто работал,
для всех документов:
db.screen.update({stat:"PRO"} , {$set : {stat:"pro"}}, {multi:true})
для одного документа:
db.screen.update({stat:"PRO"} , {$set : {stat:"pro"}}, {multi:false})