我对MongoDB& Mongoose似乎无法找到关于如何在架构更改时处理迁移的答案。
我习惯于运行迁移SQL脚本来改变表结构和需要更改的任何底层数据。这通常涉及数据库停机时间。
这通常如何在MongoDB / Mongoose中处理?我需要注意哪些问题?
答案 0 :(得分:21)
通过了解并合理地理解迁移在关系数据库上的工作方式,MongoDB使这一点变得更加简单。我有两种方法来打破这种局面。在处理MongoDB中的数据迁移时要考虑的事情(并非RDB中不常见):
1)如果您的更改会将所有人都记录下来或预计应用程序停机,那么执行此操作的简单方法是使用迁移脚本连接到本地或实时MongoDB并升级正确的数据。用户名从单个字符串更改为具有给定名称和族名的对象的示例(当然非常基本,需要放入脚本以便为所有开发人员运行):
使用CLI:
mongod
use myDatabase
db.myUsers.find().forEach( function(user){
var curName = user.name.split(' '); //need some more checks..
user.name = {given: curName[0], family: curName[1]};
db.myUsers.save( user );
})
2)您希望应用程序根据它们运行的应用程序版本上下迁移模式。这显然不会对实时服务器造成负担,并且由于仅在第一次使用升级/降级版本时仅升级用户而不需要停机时间。
如果您在Expressjs中使用Nodejs中的中间件:
app.set('schemaVersion', 1)
在根应用程序脚本中设置app变量,稍后将使用该变量与用户架构版本进行比较。 接下来,我们需要创建简单的中间件来检测配置和用户版本
app.use( function( req, res, next ){
//If were not on an authenticated route
if( ! req.user ){
next();
return;
}
//retrieving the user info will be server dependent
if( req.user.schemaVersion === app.get('schemaVersion')){
next();
return;
}
//handle upgrade if user version is less than app version
//handle downgrade if user version is greater than app version
//save the user version to your session / auth token / MongoDB where necessary
})
对于升级/降级,我将使用升级/降级导出功能在迁移目录下创建简单的js文件,这些函数将接受用户模型并在MongoDB中对该特定用户运行迁移更改。最后确保在MongoDB中更新用户版本,这样他们就不会再次运行更改,除非他们再次转移到其他版本。
答案 1 :(得分:3)
如果您已经习惯了SQL类型的迁移或类似Rails的迁移,那么您将找到适合您的cli工具migrate-mongoose。
它允许您使用up
和down
功能编写迁移,并根据迁移的成功和失败为您管理状态。
如果您使用ES 2015语法,它还支持ES6。
您可以通过this
对象访问您的mongoose模型,从而可以轻松地对模型和模式进行更改。
答案 2 :(得分:3)
有两种类型的迁移:
离线:将要求您停止维护服务,然后遍历整个集合并进行所需的更改。
在线:不需要停止维修。阅读文档时,检查其版本,并为旧版本和新版本之间的每个版本运行特定于版本的迁移例程。然后加载生成的东西。
并非所有服务都能提供离线迁移,我建议使用在线方法。