миграция данных монго с помощью рейк-подобных задач - PullRequest
0 голосов
/ 01 декабря 2011

У меня есть задача rake, предназначенная для переноса устаревших полей БД в Hash:

task :degrees => :environment do
  Person.all.each do |p|
    if p['degree1'] || p['degree2']
      p.degrees = {}
      p.degrees["first"] = p['degree1'] == "Other" ? p['degree1_other'] : p['degree1'] 
      p.degrees["second"] = p['degree2'] == "Other" ? p['degree2_other'] : p['degree2']
      p.save
    end
  end
end

Проблема в том, что это очень медленно, монго и рубин занимают 80% и 20% процессорного времени соответственно.

Для более простых миграций я смог использовать монго-обновление примерно так:

db.people.update({},{$rename : {"url" : "website"}}, false, true)

Это было очень быстро. Можно ли как-то перевести вышеуказанную задачу rake в обновление монго или скрипт оболочки?

1 Ответ

0 голосов
/ 02 декабря 2011

Я создал скрипт :

db.people.update({degree1:"Other"}, { $rename : { "degree1_other" : "degree1" } }, false, true )
db.people.update({degree2:"Other"}, { $rename : { "degree2_other" : "degree2" } }, false, true )
db.people.update({degree3:"Other"}, { $rename : { "degree3_other" : "degree3" } }, false, true )

db.people.find({degrees:null}).forEach( function (doc) {
    doc.degrees = { "first" : doc.degree1, "second" : doc.degree2, "third" : doc.degree3 };
    db.people.save(doc);
});

db.people.update({degree1: {$exists : true}},{$unset:{degree1:1}},false,true)
db.people.update({degree1_other: {$exists : true}},{$unset:{degree1_other:1}},false,true)
db.people.update({degree2: {$exists : true}},{$unset:{degree2:2}},false,true)
db.people.update({degree2_other: {$exists : true}},{$unset:{degree2_other:2}},false,true)
db.people.update({degree3: {$exists : true}},{$unset:{degree3:3}},false,true)
db.people.update({degree3_other: {$exists : true}},{$unset:{degree3_other:3}},false,true)

Он запускается в течение нескольких секунд.

...