MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Modèle de changement d'exécution avec mongodb/mongoid

En général, il devrait être possible de mettre à jour les anciens documents avec les nouveaux champs lors de l'exécution. Il n'y a pas besoin de migrations dans MongoDB.

Vous voudrez peut-être écrire des tâches de ratissage pour mettre à jour vos anciens documents avec les nouveaux champs et les valeurs par défaut.

Vous pourriez trouver ces documents en vérifiant ces nouveaux champs qui ont par défaut une valeur nulle.

Mettre à jour

Style simple :

Si vous définissez un nouveau champ avec une valeur par défaut, cette valeur doit toujours être utilisée tant que vous en définissez une nouvelle :

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

Si vous interrogez votre base de données, vous devriez obtenir votre valeur par défaut pour les documents qui n'ont pas ce champ avant votre extension :

(console de rails)

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

J'ai testé cela avec une nouvelle pile de rails avec un mongoid actuel sur Ruby 1.9.2 - devrait également fonctionner avec d'autres piles.

Style plus compliqué/complexe :

Si vous n'avez pas défini de valeur par défaut, vous obtiendrez nil pour ce nouveau champ.

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

(console de rails)

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

Ensuite, vous pouvez configurer une tâche de rake et un fichier de migration comme dans cet exemple :

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

Exécutez cette migration avec rake mymodel:migrate .

Ce n'est qu'un point de départ et vous pouvez l'étendre à un moteur de migration mongoid complet.

La task :migrate => :environment do … est nécessaire, sinon rake ne chargera pas les modèles.