2013-05-17 3 views
9

Я в процессе изменения схемы для одной из моих коллекций MongoDB. (Я сохранял даты как строки, и теперь мое приложение хранит их как ISODate, мне нужно вернуться и изменить все старые записи, чтобы использовать также ISODate.) Я думаю, что знаю, как это сделать, используя обновление , но поскольку эта операция повлияет на десятки тысяч записей, я не решаюсь выпустить операцию, которую я не уверен на 100%. Есть ли способ сделать «сухой ход» обновления, которое покажет мне, для небольшого количества записей, оригинальную запись и как она будет изменена?Есть ли способ выполнить «сухой запуск» операции обновления?


Edit: Я закончил с использованием подхода добавления нового поля для каждой записи, а затем (после проверки того, что данные прав) переименовать это поле, чтобы соответствовать оригиналу. Выглядело это так:

db.events.find({timestamp: {$type: 2}}) 
    .forEach(function (e) { 
     e.newTimestamp = new ISODate(e.timestamp); 
     db.events.save(e); 
    }) 

db.events.update({}, 
    {$rename: {'newTimestamp': 'timestamp'}}, 
    {multi: true}) 

Кстати, этот метод для преобразования строкового раза ISODate с был то, что в конечном итоге работает. (Я получил идею от this SO answer.)

+1

Моей рекомендацией было бы добавить ISODate в качестве нового поля. После подтверждения, что все выглядит хорошо, вы можете отменить дату строки. –

+0

@JamesWahlin Имеет ли правильную идею, даже в SQL, которая поддерживает сухие пробеги, я бы этого не сделал – Sammaye

+0

@JamesWahlin Можете ли вы добавить свой комментарий в качестве ответа? – bdesham

ответ

3

Мой совет будет добавить ISODate в качестве нового поля. После подтверждения, что все выглядит хорошо, вы можете отменить дату строки.

4

Создайте тестовую среду с вашей структурой базы данных. Скопируйте несколько записей на него. Задача решена. Я уверен, что это не решение, которое вы искали. Но, я считаю, это точные обстоятельства, в которых должна быть использована «тестовая среда».

+0

Я думал об этом. Но если моя первая попытка не сработает, мне придется очистить среду разработки и повторно импортировать данные - возможно, много раз - и это было похоже на хлопот, который я мог бы избежать. – bdesham

+0

Да, я предполагал, что это считалось, просто подумал, что я брошу предложение там, во всяком случае ... Иногда я иногда забываю простую вещь. – eidsonator

2

Выберите идентификатор определенных записей, которые вы хотите отслеживать. место в update{_id:{$in:[<your monitored id>]}}

+0

Это один из подходов, хотя он все еще открывает возможность уничтожения данных, если я испортил операцию обновления. – bdesham

+2

@bdesham - это плохая практика экспериментировать с живыми данными без резервного копирования. Это правило большого пальца для любых производственных манипуляций - сначала создать точку отката – Dewfy

0

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

var changesLog = []; 
var errorsLog = []; 
events.find({timestamp: {$type: 2}}, function (err, events) { 
    if (err) { 
     debugger; 
     throw err; 
    } else { 
     for (var i = 0; i < events.length; i++) { 
      console.log('events' + i +"/"+(candidates.length-1)); 
      var currentEvent = events[i]; 
      var shouldUpdateCandidateData = false; 

      currentEvent.timestamp = new ISODate(currentEvent.timestamp); 


      var change = currentEvent._id; 
      changesLog.push(change); 

      // // ** Dry Run ** 
      //  currentEvent.save(function (err) { 
      //   if (err) { 
      //    debugger; 
      //    errorsLog.push(currentEvent._id + ", " + currentEvent.timeStamp + ', ' + err); 
      //    throw err; 
      //   } 
      //  }); 
     } 
     console.log('Done'); 
     console.log('Changes:'); 
     console.log(changesLog); 
     console.log('Errors:'); 
     console.log(errorsLog); 
     return; 
    } 
}); 
Смежные вопросы