我是否应该始终 post 将整个文档更新为更新 MongoDB 的命令?
Should I always post a the whole document to a command that updates MongoDB?
我有一个 AngularJS 应用程序,它由 .NET 核心 CQRS API 和 MongoDB 数据库支持。虽然我非常了解和理解大多数技术,但 MongoDB 和文档数据库作为一个整体对我来说是新的,我仍在学习中。
最简单形式的数据是最多可具有 3 层层次结构(顶级、组级别和最终节点)的文档。当文档首次创建并插入 Mongo 数据库时,它根本没有 tiers/nodes 只有高级信息,如姓名、作者等。然后在 UI 中,用户可以添加任意数量的新组和这些组中的最终节点。
在关系数据库中,我会简单地 post 向将插入新行的命令提供必要的信息,并且该命令将被称为 'AddNewGroup'。我不需要 post 所有信息,只需要密钥 ID 和要插入的新信息。
但是,这种方法对于 Mongo 似乎并不正确。我假设我应该 post 整个文档并有一个覆盖数据库中现有文档的更新命令是否正确?或者有更好的方法吗?
我还应该将我的命令分解为正在完成的特定类型的更新,例如UpdateAuthorName、AddNewGroup 等,如果整个文档总是被更新。
您的文档是写入模型,是域驱动设计世界中的聚合。作为没有事件源的 CQRS,您需要将文档状态与生成的事件一起存储。您还需要防止并发写入。也就是说,您有两个选择:
- 对于每个命令,您仅更新更改的 nested-document,即文档的 header。
它的优点是速度快,并发修改异常的可能性较低,如果您对每个文档部分都有单独的保护(即每个文档的 version
属性与单个 version
用于整个文档)。
它的缺点是它将域模型 (class) 与基础架构结合得太多,因为您需要将查询放在文档 class 中。如果将域与基础结构混合,那么您将不再拥有纯模型,并且您将失去安全重试命令的能力。如果您 "teach" 基础架构存储库根据发出的事件做出不同反应,这可以在域 class 之外的基础架构中完成。
这也表明您实际上有多个写入模型,每个模型用于文档的部分(header、body、页脚、注释等),因为写入模型是指定的由一致性边界。在这种情况下,他们将共享相同的文档 ID。
- 对于所有命令,您将替换整个文档,无论内部发生了什么变化。
它的巨大优势在于您可以拥有一个纯域 class,而无需依赖任何基础架构。基础设施只是获取整个状态并替换持久状态并在同一事务中附加新事件。
它的缺点是比第一个解决方案慢。 如果您遵循 DDD 方法,这就是您将文档识别为聚合后的课程(在 DDD 中,聚合已完全加载并完全持久化以响应执行命令)。
我有一个 AngularJS 应用程序,它由 .NET 核心 CQRS API 和 MongoDB 数据库支持。虽然我非常了解和理解大多数技术,但 MongoDB 和文档数据库作为一个整体对我来说是新的,我仍在学习中。
最简单形式的数据是最多可具有 3 层层次结构(顶级、组级别和最终节点)的文档。当文档首次创建并插入 Mongo 数据库时,它根本没有 tiers/nodes 只有高级信息,如姓名、作者等。然后在 UI 中,用户可以添加任意数量的新组和这些组中的最终节点。
在关系数据库中,我会简单地 post 向将插入新行的命令提供必要的信息,并且该命令将被称为 'AddNewGroup'。我不需要 post 所有信息,只需要密钥 ID 和要插入的新信息。
但是,这种方法对于 Mongo 似乎并不正确。我假设我应该 post 整个文档并有一个覆盖数据库中现有文档的更新命令是否正确?或者有更好的方法吗?
我还应该将我的命令分解为正在完成的特定类型的更新,例如UpdateAuthorName、AddNewGroup 等,如果整个文档总是被更新。
您的文档是写入模型,是域驱动设计世界中的聚合。作为没有事件源的 CQRS,您需要将文档状态与生成的事件一起存储。您还需要防止并发写入。也就是说,您有两个选择:
- 对于每个命令,您仅更新更改的 nested-document,即文档的 header。
它的优点是速度快,并发修改异常的可能性较低,如果您对每个文档部分都有单独的保护(即每个文档的 version
属性与单个 version
用于整个文档)。
它的缺点是它将域模型 (class) 与基础架构结合得太多,因为您需要将查询放在文档 class 中。如果将域与基础结构混合,那么您将不再拥有纯模型,并且您将失去安全重试命令的能力。如果您 "teach" 基础架构存储库根据发出的事件做出不同反应,这可以在域 class 之外的基础架构中完成。
这也表明您实际上有多个写入模型,每个模型用于文档的部分(header、body、页脚、注释等),因为写入模型是指定的由一致性边界。在这种情况下,他们将共享相同的文档 ID。
- 对于所有命令,您将替换整个文档,无论内部发生了什么变化。
它的巨大优势在于您可以拥有一个纯域 class,而无需依赖任何基础架构。基础设施只是获取整个状态并替换持久状态并在同一事务中附加新事件。
它的缺点是比第一个解决方案慢。 如果您遵循 DDD 方法,这就是您将文档识别为聚合后的课程(在 DDD 中,聚合已完全加载并完全持久化以响应执行命令)。