如何处理mongodb“模式”生产中的变化

我使用mongodb + node.js + mongoose.js ORM后端。

假设我有一些没有_id字段的嵌套对象数组

mongoose.Schema({ nested: [{ _id: false, prop: 'string' }] }) 

然后我想广告_id字段到所有嵌套对象,所以mongoose模式将是

 mongoose.Schema({ nested: [{ prop: 'string' }] }) 

然后我应该运行一些脚本来修改生产数据库,对不对? 处理这种变化的最好方法是什么? 哪个工具(或方法)最适合用来实现这个变化?

无模式数据库的一个显着优点是您不必使用新的模式布局来更新整个数据库。 如果数据库中的一些文档没有特定的信息,那么你的代码可以做适当的事情,或select现在做任何与该logging。

另一个select是根据需要懒惰地更新文件 – 只有当他们再次看。 在这种情况下,您可能会select每个logging/文档版本标志 – 最初甚至可能不会出现(因此表示“版本0”)。 即使这是可选的。 相反,你的数据库访问代码会查找它所需要的数据,如果它不存在,因为它是新的信息,在代码更新后添加,那么它将尽可能地填充结果。

例如,将_id:false转换为标准的MongoId字段,当代码被读取(或在更新后被写回),并且_id:false当前被设置,然后进行修改并且只在绝对需要。

您确实必须编写将覆盖集合的脚本,并为每个文档添加一个新字段。 但是,确切的方式取决于数据库的大小和存储系统的性能。 在文档中添加一个字段将会改变其大小,从而导致大多数情况下的重定位。 这个操作对IO有影响,也受到它的限制。 如果你的集合只有几千个文档,可能会达到十万个,那么你可能只是在一个循环中迭代它,因为整个集合可能适合内存,所有的IO将在随后发生。 但是,如果收集范围远远超出可用内存,则方法更为复杂。 我们通常会遵循MongoDB生产使用的下一个步骤:

  • 用timeout = False打开游标
  • 将大量文件读入内存
  • 对这些文档运行更新查询
  • hibernate一段时间以避免IO子系统过载并伤害生产应用
  • 重复,直到完成
  • closures光标:)

文件大小和睡眠时间必须通过实验确定。 通常情况下,您希望在迁移期间避免在mongostats中使用QR / QW。 对于速度较慢的驱动器(如Amazon上的EBS)上的较大集合,此IO安全方法可能需要数小时至数天。