3

我最近一直在学习如何将 MongoDB 与 Node.js 一起使用,并且一直想知道如何与团队的其他成员共享 MongoDB 更改,例如,通过 git 存储库。

例如,如果我需要一个users在 MongoDB 中命名的集合,并且该集合有一些包含字段givenName和的文档familyName,这将很容易做到,因为当团队中的每个开发人员运行该应用程序时,MongoDB 将自动创建该集合和字段,因为它们是在代码中编写的。

现在让我们说由于某种原因我需要将两个字段重命名为forenameand surname

该应用程序已经运行了一段时间,因此团队中的所有开发人员都拥有该users集合的本地副本,其中包含带有givenName和的文档familyName;生产服务器也是如此。

据我了解,我不能简单地将代码中的字段名称更改为使用新字段名称,因为我们会“丢失”旧字段名称中使用的任何数据(“丢失”我当然是指我们只是不会再看到旧数据,即使它仍然存在,正如预期的那样)。

所以我想我还必须在 MongoDB shell 中运行一个命令来重命名所有相关文档中的字段。

但如果我这样做,那么只有我的本地users集合副本是最新的。

使用 MySQL 时,我们要么在需要时运行的 SQL 文件中通过 git 共享所有更改,要么在可用时使用迁移,例如在 PHP 中的 Laravel 框架中。

我们是否会像使用 MySQL 一样做同样的事情,并保留changes.js我们在 MongoDB shell 中运行的文件?

或者有没有更好的方法来做到这一点,也许在应用程序代码本身中,以便在开发人员运行应用程序时自动运行更改?

换句话说,在团队成员之间共享 MongoDB 更改的最佳实践是什么?

4

1 回答 1

1

对于几乎所有持久性系统来说,数据迁移都是一个巨大的痛苦。有两大策略:懒惰迁移和急切迁移。

对于惰性迁移,您需要您的代码能够同时处理新旧数据结构。不幸的是,我不知道 node.js mongodb 驱动程序在内部是如何工作的。例如,在 C# 驱动程序中,可以注册自定义序列化程序、定义别名或使用 C# 的 getter 和 setter 来启用此行为。因此,该Forename字段将从givenName or Forename中读取,但是当将其存储回数据库时,它将始终被序列化为Forename.

这种策略的问题在于它不适用于查询,例如{"Forename" : "John"}由于某些文档尚未迁移而失败。当然,索引甚至唯一约束会使事情变得更糟。

急切的迁移需要某种脚本,它基本上会遍历数据库中的所有文档并根据您的需要更新它们。通常,这是更简单的路径,并且不会中断查询。但是,您需要在正确的时间运行此脚本,而对于大型数据集,这可能需要一段时间。在此期间,您的系统要么停机,要么提供不正确的结果。

因此,数据量越大,必须允许的“懒惰”越多。例如,您可能希望按用户运行脚本(而不是按自然顺序),这样用户就不太可能达到其数据的“半迁移”状态。尽管如此,您仍希望您的代码能够处理此问题。

对于这两种策略,当事情变得复杂时,可能需要模式版本控制,即单个文档有一个类似的字段,_sv并且有知道如何从一个版本n到另一个版本的脚本n+1。然后,您可以使脚本非常抽象和幂等,这样您就可以运行它们,而不必担心在新数据上运行旧脚本会破坏任何东西。

于 2013-10-16T09:12:35.773 回答