处理Mongoose中的模式更改

79

在应用程序不断发展的过程中,更新/迁移Mongoose模式的最佳实践(或工具)是什么?

3个回答

43

有趣的是,MongoDB诞生的目的就是为了解决关系型数据库中存在的架构问题。如果字段是必填项,您只需要在架构定义中设置默认值,而无需迁移任何内容。

new Schema({
    name: { type: string }
})

收件人:

new Schema({
    name: { type: string },
    birthplace: { type: string, required: true, default: 'neverborn' }
});

5
我认为它与SQL数据库并没有太大的区别。例如,您可能会将“姓名”拆分为“名字”和“姓氏”字段...您需要对每个环境的数据库运行该转换,并以某种方式进行跟踪。 - mahemoff
20
你无需“迁移”模式(好吧,某种程度上来说,如果实际不存在模式,则可能仍需迁移索引等内容),但你必须迁移实际数据。 - mahemoff
1
我正在添加一个必填字段,并在.save()时填充,但是现有数据都没有它。因此,我需要对所有数据调用save()来获取它。我们需要一种方法来迁移express/mongoose应用程序中的数据。 - chovy
2
你正在尝试修复历史记录。你应该使用插件来代替。 - vimdude
3
好的,我也有一个类似的情况。虽然目前还没有发生这种情况,但是我有一个非常庞大的架构,我知道它需要随着时间不断变化。那么,如果我要访问在先前版本的架构中创建的集合项,该怎么办呢?Mongoose 里面有什么神奇的方法吗? - regretoverflow
显示剩余11条评论

7

我遇到了一个问题,我需要更新我的数据库以反映我的模式的更改。经过一些研究,我决定尝试在mongo控制台中使用updateMany()函数进行更新,我认为它运行得非常好。

要将此应用于vimdude的示例,则代码如下:

try { 
    db.<collection>.updateMany( { birthplace: null }, { $set: 
              {"birthplace": "neverborn" } } ); 
} catch(e) { 
    print(e);
}

updateMany()函数将根据过滤器更新集合中的所有文档。在这种情况下,过滤器正在查找字段“birthplace”为空的所有文档。然后,在这些文档中设置一个名为“birthplace”的新字段,并将其值设置为“neverborn”。

运行代码后,根据您的情况进行修改并运行:

db.<collection>.find().pretty()

为了验证更改已经完成,您的集合中每个文档的末尾应该显示带有值“neverborn”的新字段“birthplace”。

希望这有所帮助。


6
更新:测试过了,当前形式下这并不起作用,它有一个正确的想法,我通过对模块本身进行大量调整,使单个迁移工作。但是,我认为如果不进行一些重大更改并以某种方式跟踪不同的模式,它将无法按预期工作。
听起来你想要使用mongoose-data-migrations
这个工具旨在在你使用文档时迁移旧版本的模式,这似乎是处理mongodb迁移的最佳方式。
你真的不希望在文档集合上运行完整的数据集迁移(例如alter table),因为它会给服务器带来沉重的负载并可能需要应用程序/服务器停机时间。有时您可能需要编写一个脚本,它简单地获取所有文档并应用新的模式/修改,然后调用save,但您需要了解何时/在何处执行该操作。例如,在doc init中添加迁移逻辑比关闭服务器3小时以运行迁移脚本的性能损失更大。
我也发现link对此非常有帮助,基本上更详细地重申了以上内容,并在php中实现了上述节点包的概念。
注:该模块有5个月的历史记录,0个分支,但是我正在四处查找,找不到比abdelsaid的响应方式更好/更有帮助的东西。

1
更新了。不幸的是,它相当有问题。如果您找到任何解决方案,请在此通知我,因为我希望能够找到适合更新的方法。我有一种感觉,您需要跟踪每个版本以便加载旧模式并允许修改,就像该模块试图做的那样。但是,我的mongoose知识还相当缺乏。我正在努力学习! - lsl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接