Как ограничить количество обновляемых документов в mongodb - PullRequest
43 голосов
/ 06 июля 2011

Как реализовать что-то похожее на db.collection.find().limit(10), но при обновлении документов?

Теперь я использую что-то действительно дурацкое, например, получаю документы с db.collection.find().limit() и затем обновляю их.

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

Спасибо.

Ответы [ 6 ]

34 голосов
/ 03 августа 2013

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

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, например, только к половине ваших записей в «collection», вы можете вставить

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} );
11 голосов
/ 06 июля 2011

К сожалению, обходной путь у вас есть единственный способ сделать это AFAIK. Существует логический флаг multi, который либо обновляет все совпадения (когда true), либо обновляет 1-е совпадение (когда false).

9 голосов
/ 09 июля 2014

Решения, которые перебирают все объекты, а затем обновляют их по отдельности, очень медленные.

Извлечение их всех и последующее обновление с использованием $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.

7 голосов
/ 10 ноября 2017

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

ids = db.collection.find(<condition>).limit(<limit>).map(
    function(doc) {
        return doc._id;
    }
);
db.collection.updateMany({_id: {$in: ids}}, <update>})
1 голос
/ 25 апреля 2014

Как говорится в ответе, до сих пор нет способа ограничить количество документов, которые нужно обновить (или удалить), значением> 1. Обходной путь для использования чего-то вроде:

db.collection.find(<condition>).limit(<limit>).forEach(function(doc){db.collection.update({_id:doc._id},{<your update>})})
0 голосов
/ 06 июля 2011

Не уверен, какова цель применения ограничения на обновления (даже невозможно в SQL). Как омар: обновление работает только для одного документа или для всех документов, соответствующих критериям обновления. Поэтому вы должны настроить критерии в соответствии со своими потребностями или обновить их по одному на основе предыдущего запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...