管理 mongoid 迁移

Posted

技术标签:

【中文标题】管理 mongoid 迁移【英文标题】:Managing mongoid migrations 【发布时间】:2012-01-24 03:16:43 【问题描述】:

有人可以简要介绍一下在 Rails 中使用 Mongoid 进行数据库迁移吗?我对每个文档迁移的惰性特别感兴趣。我的意思是,每当您从数据库中读取文档时,您都会将其迁移到其最新版本并再次保存。

以前有人做过这种事吗?我遇到过mongoid_rails_migrations,但它没有提供任何类型的文档,虽然它看起来像这样做,但我不确定如何使用它。

我应该指出我只在概念上熟悉 ActiveRecord 迁移。

【问题讨论】:

我不认为惰性迁移是一个好主意。我宁愿花时间运行大规模的数据更新,等待它完成,监控,想办法在出现任何问题时恢复,然后首先在数据库克隆上进行测试。这需要时间,但不会给您留下数据不一致的问题。 【参考方案1】:

Zachary Anker 在他的回答中解释了很多。使用 mongoid_rails_migrations 是迁移的好选择。

这里有一些带有示例的链接,对您浏览和使用mongoid_rails_migrations很有帮助

Mongoid Migrations using the Mongo Driver

Embedding Mongoid documents and data migrations

除此之外,Readme 应该足以通过此示例实现 mongoid 迁移

【讨论】:

【参考方案2】:

我也有同样的需要。

这是我想出的:https://github.com/nviennot/mongoid_lazy_migration

我很高兴收到一些反馈

【讨论】:

【参考方案3】:

如果您想一次完成整个迁移,那么 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_namelast_name 字段。

【讨论】:

以上是关于管理 mongoid 迁移的主要内容,如果未能解决你的问题,请参考以下文章

ruby 将Mongoid / MongoDB数据库迁移到基于ActiveRecord的SQL数据库。一种转换架构的方法,另一种转换数据的方法。应对

gem 'mongoid', '~> 4' 是不是等于 gem 'mongoid', '>= 4'?

如何跳过 Mongoid 文档的回调?

mongoid 中的索引:我应该何时以及多久运行一次 rake db:mongoid:create_indexes?

Mongoid 时间戳索引

mongoid 索引仍然导致 COLLSCAN