MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Laufzeitänderungsmodell mit Mongodb/Mongoid

Generell sollte es möglich sein, alte Dokumente zur Laufzeit mit den neuen Feldern zu aktualisieren. Migrationen in MongoDB sind nicht erforderlich.

Vielleicht möchten Sie Rake-Tasks schreiben, um Ihre alten Dokumente mit den neuen Feldern und Standardwerten zu aktualisieren.

Sie können diese Dokumente herausfinden, indem Sie die neuen Felder überprüfen, die standardmäßig einen Nullwert haben.

Aktualisieren

Einfacher Stil:

Wenn Sie ein neues Feld mit einem Standardwert definieren, sollte dieser Wert immer verwendet werden, solange Sie einen neuen festlegen:

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

Wenn Sie Ihre Datenbank abfragen, sollten Sie Ihren Standardwert für Dokumente erhalten, die dieses Feld nicht vor Ihrer Erweiterung haben:

(Schienenkonsole)

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

Ich habe dies mit einem frischen Rails-Stack mit einem aktuellen Mongoid auf Ruby 1.9.2 getestet - sollte auch mit anderen Stacks funktionieren.

Komplizierterer/komplexerer Stil:

Wenn Sie keinen Standardwert festgelegt haben, erhalten Sie für dieses neue Feld null.

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

(Schienenkonsole)

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

Dann könnten Sie eine Rake-Aufgabe und eine Migrationsdatei wie in diesem Beispiel einrichten:

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

Führen Sie diese Migration mit rake mymodel:migrate aus .

Dies ist nur ein Ausgangspunkt und Sie können dies zu einer vollständigen Mongoid-Migrations-Engine erweitern.

Die task :migrate => :environment do … ist notwendig, sonst lädt Rake keine Modelle.