23

我正在构建一个使用 MongoDB 作为后端和 MongoMapper 作为 ORM 工具的 Rails 应用程序。假设在版本 1 中,我定义了以下模型:

class SomeModel
  include MongoMapper::Document
  key :some_key, String
end

后来在版本 2 中,我意识到我需要模型上的新必需键。因此,在版本 2 中,SomeModel 现在看起来像这样:

class SomeModel
  include MongoMapper::Document
  key :some_key, String
  key :some_new_key, String, :required => true
end

如何迁移所有现有数据以包含 some_new_key?假设我知道如何为所有现有文档设置合理的默认值。更进一步,假设在版本 3 中,我意识到我真的根本不需要 some_key。所以,现在模型看起来像这样

class SomeModel
  include MongoMapper::Document
  key :some_new_key, String, :required => true
end

但是我数据库中的所有现有记录都为 some_key 设置了值,此时它只是在浪费空间。我如何回收该空间?

使用 ActiveRecord,我将创建迁移以添加 some_new_key 的初始值(在 version1 -> version2 迁移中)并删除 some_key 的值(在 version2 -> version3 迁移中)。

使用 MongoDB/MongoMapper 执行此操作的适当方法是什么?在我看来,一些跟踪已运行迁移的方法仍然是必要的。这样的事情存在吗?

编辑:我认为人们错过了我的问题的重点。有时您希望能够在数据库上运行脚本来更改或重组其中的数据。我在上面给出了两个示例,一个是添加了新的必需密钥,一个是可以删除密钥并可以回收空间的示例。您如何管理运行这些脚本?ActiveRecord 迁移为您提供了一种简单的方法来运行这些脚本并确定哪些脚本已经运行以及哪些脚本尚未运行。我显然可以编写一个对数据库进行任何更新的 Mongo 脚本,但我正在寻找的是一个像迁移这样的框架,它可以让我跟踪哪些升级脚本已经运行。

4

9 回答 9

13

看看 Mongrations... 我刚读完它,它看起来就像你所追求的。

http://terrbear.org/?p=249

http://github.com/terrbear/mongrations

干杯! 卡普斯洛克

于 2010-03-15T06:05:37.677 回答
1

一种选择是使用该update操作一次更新所有数据。多更新是开发版本中的新功能,因此您需要使用其中之一。

于 2009-11-20T19:26:10.060 回答
1

也是 MongoMapper 迁移的另一个宝石https://github.com/alexeypetrushin/mongo_mapper_ext

于 2011-05-18T22:56:38.437 回答
1

你可以试试我刚刚制作的这个装置,但目前它只适用于 mongoid 和 rails 3 (beta 3)。http://github.com/adacosta/mongoid_rails_migrations。当它进入最终版本时,它将升级到 Rails 3。

于 2010-05-13T15:19:54.937 回答
1

Mongrations 是一个超级古老的宝石,完全不推荐使用。我建议不要使用它。

Exodus 是一个非常酷的 Mongo 迁移框架,这可能是你想要的:

https://github.com/ThomasAlxDmy/Exodus

于 2013-11-13T18:38:29.693 回答
1

我们只是构建了这个:https ://github.com/eberhara/mongration - 它是一个常规节点模块(你可以在 npm 上找到它)。

我们需要一个好的 mongodb 迁移框架,但是找不到——所以我们构建了一个。

与常规迁移框架相比,它具有许多更好的功能:

  • 校验和(当先前运行的迁移与其旧版本不匹配时发出错误)
  • 将迁移状态持久化到 mongo(没有常规状态文件)
  • 完全支持副本集
  • 自动处理回滚(开发人员必须指定回滚过程)
  • 能够同时运行多个迁移(同步或异步)
  • 能够同时针对不同的数据库运行迁移

希望能帮助到你!

于 2015-12-14T16:46:36.653 回答
0

克林特,

您可以编写代码来进行更新——尽管似乎不支持根据自己的字段更新记录。

在这种情况下,我做了以下操作并针对服务器运行它:

------------------------------
records = Patient.all()

records.each do |p|
  encounters = p.encounters
  if encounters.nil? || encounters.empty?
    mra = p.updated_at
    #puts "\tpatient...#{mra}"
  else
    mra = encounters.last.created_at
    #puts "\tencounter...#{mra}"
  end
  old = p.most_recent_activity
  p.most_recent_activity = mra
  p.save!
  puts "#{p.last_name} mra: #{old} now: #{mra}"
end
------------------------------
于 2010-07-28T17:37:41.380 回答
-1

我敢打赌,您可以使用 Activerecord::Miration 来自动化和跟踪您的“迁移”脚本。

于 2010-02-12T17:11:59.617 回答
-5

MongoDB 是一个无模式数据库。这就是为什么没有迁移。在数据库本身中,对象在任何时候是否具有键 :some_key 或键 :some_other_key 都无关紧要。

MongoMapper 尝试对此实施一些限制,但由于数据库非常灵活,您必须自己维护这些限制。如果您需要每个对象上的键,请确保运行脚本来更新预先存在的对象上的这些键,或者在遇到对象时处理没有该键的对象的情况。

我本人对 MongoDB 还很陌生,但据我所知,由于无模式数据库的灵活性,这就是您需要处理它的方式。

于 2009-11-20T18:09:00.147 回答