sql >> Databáze >  >> NoSQL >> MongoDB

Změňte typ pole v Mongoidu bez ztráty dat

Ok, zvládl jsem to. Myslím, že existuje rychlejší způsob použití mongo konzole s něčím takovým:MongoDB:Jak změnit typ pole?

Ale nemohl jsem zprovoznit konverzi, takže jsem se rozhodl pro tuto pomalejší metodu v konzole rails s delšími prostoji. Pokud má někdo rychlejší řešení, pošlete ho.

  • vytvořte nové pole Integer s novým názvem, řekněte amount2
  • převést každou amount na správnou hodnotu pro amount2 v úloze konzole nebo rake

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

Všimněte si, že .all.each funguje dobře (nemusíte používat .find_each nebo .find_in_batches jako běžný activerecord s mysql) kvůli mongodb kurzorům. Dokud je identita_map vypnutá, nezaplní paměť.

  • sundejte web z důvodu údržby, spusťte migraci ještě jednou, abyste zachytili všechna pole množství, která se mohla v posledních několika minutách změnit (něco jako Transaction.where(:updated_at.gt => 1.hour.ago).each_with_index...

  • komentovat field :amount, type: BigDecimal ve vašem modelu už nechcete, aby mongoid věděl o tomto poli, a vložte tento kód

  • nyní spusťte další skript pro přejmenování sloupce (přepíše všechny staré hodnoty řetězce BigDecimal v procesu). Možná budete muset okomentovat všechna ověření modelu, která očekávají staré pole.

Mongoid.identity_map_enabled = false
Transaction.all.each_with_index do |t,i|
  puts i if i%1000==0
  t.rename :amount2, :amount
end

Toto je atomické a nevyžaduje uložení modelu.

  • aktualizujte svůj model tak, aby odrážel nový typ sloupce field :amount, type: Integer
  • nasadit a obnovit web

Jak již bylo zmíněno, myslím, že existuje lepší způsob, takže pokud má někdo nějaké tipy, podělte se. Díky!




  1. ImportError:Žádný modul s názvem redis

  2. Použití Redis s Node.js a Socket.IO

  3. Pochopení WriteConcern v MongoDB C#

  4. Vylepšete agregační strukturu MongoDB