Java, MongoDB: Как обновлять каждый объект, итерации огромной коллекции?

У меня есть коллекция около 1 миллиона записей по 20 полей каждая. Мне нужно обновить целое число flag в каждой записи (документе), присваивая случайным образом 1 или 2 этому полю flag. Как это сделать при повторении курсора над полной коллекцией? Не кажется хорошей идеей искать второй раз для объекта, уже найденного MongoDB, чтобы обновить его:

  DBCursor cursor = coll.find();
  try {
     while(cursor.hasNext()) {
    BasicDBObject obj = (BasicDBObject) cursor.next();
    ...
    coll.update(query,newObj)

     }
  } finally {
     cursor.close();
  }

Как обновить поле в каждом документе огромной коллекции MongoDB с разными значениями эффективно?

Ответ 1

Ваш подход в основном правильный. Однако я бы не рассматривал такую ​​коллекцию как "огромную", Вы можете запустить что-то подобное из оболочки:

coll.find({}).forEach(function (doc) {
    doc.flag = Math.floor((Math.random()*2)+1);
    coll.save(doc);
 });

В зависимости от вашей версии MongoDB, конфигурации и загрузки это может занять от нескольких минут до нескольких часов

Если вы хотите выполнить это обновление в пакетах, используйте некоторые условия в вашем документе запроса, например, coll.find({"aFiled" : {$gt : minVal}, "aFiled" : {$lt : maxVal}})

Ответ 2

Мое решение для моего собственного вопроса, вдохновленное @orid:

public void tagAll(int min, int max) {
    int rnd = 0;
    DBCursor cursor = this.dataColl.find();
    try {
        while (cursor.hasNext()) {
            BasicDBObject obj = (BasicDBObject) cursor.next();
            rnd = min + (int) (Math.random() * ((max - min) + 1));
            obj.put("tag", rnd);
            this.dataColl.save(obj);
        }
    } finally {
        cursor.close();
    }
}