sql >> データベース >  >> NoSQL >> MongoDB

データを失うことなくMongoidのフィールドのタイプを変更する

    了解しました。次のようなもので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
    • サイトを展開してバックアップします

    前述のように、もっと良い方法があると思いますので、誰かがいくつかのヒントを持っているなら共有してください。ありがとう!




    1. MongoDBを使用して配列から特定のアイテムを削除する

    2. phpMyAdminはMySQLforRedisと同等ですか?

    3. 子でのMongoDBの並べ替え

    4. マングースのクエリ結果は読み取り専用ですか?