了解しました。次のようなものでmongoコンソールを使用するより速い方法があると思います: MongoDB:フィールドのタイプを変更するにはどうすればよいですか?
しかし、変換を機能させることができなかったため、ダウンタイムが長く、レールコンソールでこの低速な方法を選択しました。誰かがより速い解決策を持っているなら、それを投稿してください。
- 新しい名前、たとえば
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
mongodbカーソルがあるため、.all.eachは正常に機能することに注意してください(mysqlで通常のactiverecordのように.find_eachまたは.find_in_batchesを使用する必要はありません)。 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
- サイトを展開してバックアップします
前述のように、もっと良い方法があると思いますので、誰かがいくつかのヒントを持っているなら共有してください。ありがとう!