Ответ 1
К сожалению, обходной путь, который у вас есть, - это единственный способ сделать это AFAIK. Существует флаг boolean multi
, который либо обновит все совпадения (когда true
), либо обновит первое соответствие (когда false
).
Как реализовать что-то похожее на db.collection.find().limit(10)
, но при обновлении документов?
Теперь я использую что-то действительно дрянное, как получение документов с db.collection.find().limit()
, а затем их обновление.
В общем, я хочу вернуть заданное количество записей и изменить одно поле в каждом из них.
Спасибо.
К сожалению, обходной путь, который у вас есть, - это единственный способ сделать это AFAIK. Существует флаг boolean multi
, который либо обновит все совпадения (когда true
), либо обновит первое соответствие (когда false
).
Вы можете использовать:
db.collection.find().limit(NUMBER_OF_ITEMS_YOU_WANT_TO_UPDATE).forEach(
function (e) {
e.fieldToChange = "blah";
....
db.collection.save(e);
}
);
(Кредиты для кода forEach: MongoDB: обновление документов с использованием данных из того же документа)
Что это будет делать, это изменить только количество записей, которые вы указали. Поэтому, если вы хотите добавить поле "newField" со значением 1 только к половине ваших записей внутри "коллекции", например, вы можете добавить
db.collection.find().limit(db.collection.count() / 2).forEach(
function (e) {
e.newField = 1;
db.collection.save(e);
}
);
Если вы хотите, чтобы вторая половина также имела "newField", но со значением 2, вы можете сделать обновление с условием, что newField не существует:
db.collection.update( { newField : { $exists : false } }, { $set : { newField : 2 } }, {multi : true} );
Решения, которые перебирают все объекты, а затем обновляют их по отдельности, очень медленны.
Получение их всех, а затем обновление с использованием $in
является более эффективным.
ids = People.where(firstname: 'Pablo').limit(10000).only(:_id).to_a.map(&:id)
People.in(_id: ids).update_all(lastname: 'Cantero')
Запрос написан с использованием Mongoid, но его можно легко переписать и в Mongo Shell.
Использование forEach
для индивидуального обновления каждого документа происходит медленно. Вы можете обновлять документы навалом, используя
ids = db.collection.find(<condition>).limit(<limit>).map(
function(doc) {
return doc._id;
}
);
db.collection.updateMany({_id: {$in: ids}}, <update>})
Как сказано в ответе, пока еще нет способа ограничить количество документов для обновления (или удаления) до значения > 1. Обходной путь для использования чего-то вроде:
db.collection.find(<condition>).limit(<limit>).forEach(function(doc){db.collection.update({_id:doc._id},{<your update>})})
Не уверен, что цель применения ограничения на обновления (даже не возможна в SQL). Как омара worte: обновление работает только на одном документе или на всех документах, соответствующих критериям обновления. Итак, вы должны скорректировать критерии по вашим потребностям или обновить по одному на основе предыдущего запроса.