sql >> Base de Datos >  >> NoSQL >> MongoDB

Modelo de cambio de tiempo de ejecución con mongodb/mongoid

En general, debería ser posible actualizar los documentos antiguos con los nuevos campos en tiempo de ejecución. No hay necesidad de migraciones en MongoDB.

Tal vez desee escribir tareas de rake para actualizar sus documentos antiguos con los nuevos campos y valores predeterminados.

Puede averiguar estos documentos comprobando los nuevos campos que tienen por defecto un valor nulo.

Actualizar

Estilo sencillo:

Si define un nuevo campo con un valor predeterminado, este valor siempre debe usarse siempre que establezca uno nuevo:

app/modelos/mi_modelo.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 consulta su base de datos, debe obtener su valor predeterminado para los documentos que no tienen este campo antes de su extensión:

(consola de rieles)

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

Probé esto con una nueva pila de rieles con un mongoide actual en Ruby 1.9.2; también debería funcionar con otras pilas.

Estilo más complicado/complejo:

Si no estableció un valor predeterminado, obtendrá cero para este nuevo campo.

app/modelos/mi_modelo.rb

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

(consola de rieles)

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

Luego podría configurar una tarea de rake y un archivo de migración como en este ejemplo:

lib/tasks/my_model_migration.rake:

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

db/migrar.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

Ejecute esta migración con rake mymodel:migrate .

Este es solo un punto de partida y puede extenderlo a un motor de migración mongoid completo.

La task :migrate => :environment do … es necesario, de lo contrario el rastrillo no cargará modelos.