MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Modello che cambia runtime con mongodb/mongoid

In generale dovrebbe essere possibile aggiornare i vecchi documenti con i nuovi campi in fase di esecuzione. Non sono necessarie migrazioni in MongoDB.

Potresti voler scrivere attività di rake per aggiornare i tuoi vecchi documenti con i nuovi campi e valori predefiniti.

Potresti scoprire questi documenti controllando quei nuovi campi che hanno per default un valore nullo.

Aggiorna

Stile semplice:

Se definisci un nuovo campo con un valore predefinito, questo valore dovrebbe essere sempre utilizzato fintanto che ne imposti uno nuovo:

app/models/my_model.rb

class MyModel
  include Mongoid::Document
  field :name, type: String
  field :data, type: String
  # NEW FIELD
  field :note, type: String, default: "no note given so far!"
end

Se esegui una query sul tuo database dovresti ottenere il valore predefinito per i documenti che non hanno questo campo prima della tua estensione:

(consolle dei binari)

MyModel.first
#=> #<MyModel …other fields…, note: "no note given so far!">

L'ho testato con un nuovo stack di binari con un mongoide corrente su Ruby 1.9.2 - dovrebbe funzionare anche con altri stack.

Stile più complicato/complesso:

Se non hai impostato un valore predefinito, otterrai zero per questo nuovo campo.

app/models/my_model.rb

class MyModel
  include Mongoid::Document
  field :name, type: String
  field :data, type: String
  # NEW FIELD
  field :note, type: String
end

(consolle dei binari)

MyModel.first
#=> #<MyModel …other fields…, note: nil>

Quindi potresti impostare un'attività di rake e un file di migrazione come in questo esempio:

lib/tasks/my_model_migration.rake:

namespace :mymodel do
  desc "MyModel migration task"
  task :migrate => :environment do
    require "./db/migrate.rb"
  end
end

db/migrate.rb:

olds = MyModel.where(note: nil)
# Enumerator of documents without a valid :note field (= nil)
olds.each do |doc|
  doc.note = "(migration) no note given yet"
  # or whatever your desired default value should be
  doc.save! rescue puts "Could not modify doc #{doc.id}/#{doc.name}"
  # the rescue is only a failsafe statement if something goes wrong
end

Esegui questa migrazione con rake mymodel:migrate .

Questo è solo un punto di partenza e puoi estenderlo a un motore di migrazione mongoide completo.

L'task :migrate => :environment do … è necessario, altrimenti il ​​rastrello non caricherà i modelli.