Хорошо, я справился.Я думаю, что есть более быстрый способ использования консоли Монго с чем-то вроде этого: MongoDB: Как изменить тип поля?
Но я не смог заставить работать преобразование, поэтомувыбрал этот более медленный метод в консоли rails с большим временем простоя.Если у кого-нибудь есть более быстрое решение, пожалуйста, опубликуйте его.
- создайте новое поле Integer с новым именем, скажем
amount2
- , преобразуйте каждое
amount
в правильное значение для amount2
в консольном или грабельном задании
Mongoid.identity_map_enabled = false
Transaction.all.each_with_index do |t,i|
puts i if i%1000==0
t.amount2 = t.amount.to_money
break if !t.save
end
Обратите внимание, что .all.each работает нормально (вам не нужно использовать .find_each или.find_in_batches как обычная activerecord с mysql) из-за курсоров mongodb.Он не будет заполнять память до тех пор, пока файл identity_map отключен.
отключение сайта для обслуживания, еще раз запустите миграцию, чтобы собрать все поля количества, которые могли измениться впоследние несколько минут (что-то вроде Transaction.where(:updated_at.gt => 1.hour.ago).each_with_index...
закомментируйте field :amount, type: BigDecimal
в вашей модели, вы не хотите, чтобы mongoid больше знал об этом поле, и нажмите этот код
- теперь запускаем другой скрипт для переименования вашего столбца (он перезаписывает все старые значения строки BigDecimal в процессе). Возможно, вам придется комментировать любые проверки, которые у вас есть, для модели, которые ожидают старое поле.
Mongoid.identity_map_enabled = false
Transaction.all.each_with_index do |t,i|
puts i if i%1000==0
t.rename :amount2, :amount
end
Это атомарное и не требует сохранения на модели.
- обновите вашу модель, чтобы отразить новуютип столбца
field :amount, type: Integer
- развернуть и восстановить сайт
Как уже упоминалось, я думаю, что есть лучший способ, поэтому, если у кого-то есть какие-то советы, пожалуйста, поделитесь. Спасибо!