CQRS(事件溯源):多个聚合的投影

9
我有一个与多个聚合在CQRS架构中涉及的投影问题。例如,假设我有两个聚合“WorkItem”和“Developer”,并且按顺序发生以下事件(但不是立即):
1. WorkItemCreated(workItemId) 2. WorkItemTitleChanged(workItemId,title) 3. DeveloperCreated(developerId) 4. DeveloperNameChanged(developerId,name) 5. WorkItemAssigned(workitemId,DeveloperId)
我希望创建一个开发人员-工作项的“内连接”投影。
| WorkItemId | DeveloperId | Title  | DeveloperName | ... |
|------------|-------------|--------|---------------|-----|
| 1          | 1           | FixBug | John Doe      | ... |

我做投影的方式是逐步进行的。这意味着我从数据库中加载已保存的投影,并在剩余事件到来时应用它们。
我的问题是,创建投影表行的事件是WorkItemAssigned。然而,该事件不携带先前事件的必要信息(工作项标题、开发人员名称等)。
为了在WorkItemAssigned到达时拥有所需的信息,我必须从事件存储库中加载所有事件,为所有WorkItemsDevelopers保留内存中的状态,以便在WorkItemAssigned事件到达时拥有所需的信息。
当然,我可以为WorkitemDeveloper分别创建一个投影,并查询它们以检索它们的最新状态。但如果我要为每个聚合单独创建投影,我可能会创建一个数据库视图来内部连接它们(事实上,这就是我正在做的)。
我并不是手动完成所有这些操作,我目前正在使用一个很好的框架EventFlow,但它没有直接回答我的问题。
这是关于CQRS基础的问题,我觉得我在这方面缺少了一些东西。
1个回答

7
我认为你没有遗漏任何内容。在事件溯源系统中投影读取模型会出现不同的问题,而不是从关系模型查询。这些问题不一定更容易或更难解决,只是不同。
好消息是您有很多选择。事件溯源允许您以任何想象的方式投影数据,因此您可以决定最适合每个单独投影的解决方案。我认为“不好”的消息(我会认为这不是坏消息)是解决问题的方法并不总是与关系系统相同,即使用JOIN构建查询。
您已经确定了几种可能的解决方案:
- 将关系模型用作其中一个读取模型 - 当某种类型的事件到来时,重新查询存储所需数据的流,并使用它们按需进行投影
您还可以简单地保持一些数据处于中间状态(在内存中、文档数据库、文件系统等),以便在需要时查找数据和进行投影。因此,在更新的WorkItems和Developers列表中保存这些信息,当WorkItemAssigned事件到来时,可以读取这些信息并进行投影。
我认为创建关系数据库作为中间或永久读取模型是解决问题的完全可行方法,假设您不试图实现大规模可扩展性。

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