25

Может ли кто-нибудь дать мне краткое введение в выполнение операций с DB в Rails с помощью Mongoid? Меня особенно интересует ленивая миграция документов. Под этим я подразумеваю, что всякий раз, когда вы читаете документ из базы данных, вы переносите его в свою последнюю версию и сохраняете его снова.Управление миграцией mongoid

Неужели кто-нибудь это делал раньше? Я столкнулся с mongoid_rails_migrations, но он не предоставляет какой-либо документации, и хотя похоже, что он делает это, я не уверен, как его использовать.

Следует отметить, что я только концептуально знаком с миграциями ActiveRecord.

+0

Я не думаю, что ленивые миграции являются хорошей идеей. Я бы предпочел потратить время на массовое обновление данных, дождаться его завершения, мониторинга, подумать о способе возврата, если что-то пойдет не так, и сначала проверить его на клоне базы данных. Это требует времени, но оно не оставит вас с несогласованностью данных. –

ответ

21

Если вы хотите выполнить всю миграцию сразу, то mongoid_rails_migrations будут делать то, что вам нужно. Документировать не так уж и много, он дублирует функциональность стандартной миграции ActiveRecord. Вы пишете свои миграции, а затем используете rake db:migrate, чтобы применить их, и он обрабатывает выяснение, какие из них были и не были запущены. Я могу ответить на дополнительные вопросы, если есть что-то конкретное, о чем вы хотите знать.

Для ленивых миграций самым простым решением является использование обратного вызова after_initialize. Проверьте, если поле соответствует старой схемы данных, и если оно вам изменить его объект и обновлять его, так, например:

class Person 
    include Mongoid::Document 

    after_initialize :migrate_data 

    field :name, :type => String 

    def migrate_data 
     if !self[:first_name].blank? or !self[:last_name].blank? 
      self.set(:name, "#{self[:first_name]} #{self[:last_name]}".strip) 
      self.remove_attribute(:first_name) 
      self.remove_attribute(:last_name) 
     end 
    end 
end 

Компромиссы иметь в виду, со специфическим подходом я дал выше:

Если вы запустите запрос, который возвращает много записей, например Person.all.each {|p| puts p.name}, а 100 человек имеют старый формат, он сразу же запускает 100 заданных запросов. Вы также можете вызвать self.name = "#{self.first_name} #{self.last_name}".strip, но это означает, что ваши данные будут перенесены только в том случае, если запись сохранена.

Общие проблемы, которые могут возникнуть в связи с тем, что любые массовые запросы, такие как Person.where(:name => /Foo/).count, потерпят неудачу, пока все данные не будут перенесены. Также, если вы делаете Person.only(:name).first, миграция завершится неудачно, потому что вы забыли включить поля first_name и last_name.

7

Захари Анкер многое объяснил в своем ответе. Использование mongoid_rails_migrations - хороший вариант для миграции.

Вот некоторые ссылки с примерами, которые будут полезны для вас, чтобы пройти и использовать mongoid_rails_migrations

Mongoid Migrations using the Mongo Driver

Embedding Mongoid documents and data migrations

Другой тогда этого Readme это должно быть достаточно с этим примером для реализации миграция mongoid

3

У меня такая же потребность.

Вот что я придумал: https://github.com/nviennot/mongoid_lazy_migration

Я бы с удовольствием оценил бы некоторую обратную связь

+0

Это похоже на правильную вещь, потрясающе! –