Ok jag klarade mig. Jag tror att det finns ett snabbare sätt att använda mongokonsolen med något sånt här:MongoDB:Hur ändrar man typ av fält?
Men jag kunde inte få konverteringen att fungera, så valde den här långsammare metoden i rails-konsolen med mer stillestånd. Om någon har en snabbare lösning vänligen posta den.
- skapa ett nytt heltalsfält med ett nytt namn, säg
amount2
- konvertera varje
amount
till rätt värde föramount2
i en konsol- eller rakeuppgift
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
Observera att .all.each fungerar bra (du behöver inte använda .find_each eller .find_in_batches som vanlig activerecord med mysql) på grund av mongodb-markörer. Det kommer inte att fylla upp minnet så länge som identity_map är avstängd.
-
ta ner webbplatsen för underhåll, kör migreringen en gång till för att fånga beloppsfält som kunde ha ändrats under de senaste minuterna (något som
Transaction.where(:updated_at.gt => 1.hour.ago).each_with_index...
-
kommentera
field :amount, type: BigDecimal
i din modell vill du inte att mongoid ska veta om det här fältet längre, och tryck på den här koden - kör nu ett annat skript för att byta namn på din kolumn (det skriver över alla gamla BigDecimal-strängvärden i processen). Du kan behöva kommentera eventuella valideringar du har på modellen som förväntar sig det gamla fältet.
Mongoid.identity_map_enabled = false
Transaction.all.each_with_index do |t,i|
puts i if i%1000==0
t.rename :amount2, :amount
end
Detta är atomärt och kräver ingen besparing på modellen.
- uppdatera din modell för att återspegla den nya kolumntypen
field :amount, type: Integer
- distribuera och ta upp webbplatsen igen
Som nämnt tror jag att det finns ett bättre sätt, så om någon har några tips, dela gärna. Tack!