问题描述
快速回顾:我正在使用带有 CQRS 的事件存储,并且我有 2 个名为“组”和“用户”的聚合。
基本上,用户定义了一些特征,例如他的地区、年龄和一些兴趣。
然后他可以选择与同一地区、年龄和兴趣相同的群组“匹配”。
现在是这样:“匹配”部分应该完全发生在后端,这可能是一个长时间运行的过程,但对于客户端来说,它只是对端点的 1 次调用,最终结果应该是他与一个组匹配.
因此,对于这种情况,我必须查询具有相同地区、相同年龄段的组,兴趣在我的查询中并不重要。我知道有一个组列表,媒人将根据组和用户之间的共同兴趣给每个组一个评级。评分最高的小组将加入。
再次使用 CQRS 和 ES,我的问题是这种情况似乎是查询和命令的混合,将查询混合到匹配命令中似乎违背了 CQRS 的目的。
查询多个组并根据我的写入端(事件存储)过滤它们也是一个坏主意,因为必须重新构建聚合并将其加载到内存中,然后才能将它们过滤掉。
所以我:我有点卡在这里,有些东西告诉我长时间运行的进程/传奇可以解决我的问题,但我不明白我如何仍然不会打破查询和命令的混合我的传奇,作为一个传奇基本上是一连串的命令/事件。
我如何处理这个特定案例?不需要真正的代码,让我继续前进的概念性解决方案是完美的。
解决方法
嗨,这实际上是 CQRS 可以发挥作用的案例。
对于这种情况,创建专用匹配模型似乎是理想的选择,以允许以其他形式回答可能相当重要的查询。
所以,
- 创建一个专用(可能是临时的,可能是检查点/持久化)查询模型作为派生存储。
- 根据请求运行查询以获得最匹配的结果。
- 根据查询结果发送命令以使用新链接更新事件存储。
查询模型不需要管理命令,并且可以从事件存储推送的基础上更新。这将使构建和保持更新变得相当简单,并且可以进一步优化以仅包含此特定查询所需的数据。
内存中的图可能效果很好。
-克里斯
附上
在命令方面:这里的命令每个只会更新一个聚合实例。
进一步使用预写模式将允许不需要任何类型的进程管理器或“saga”。
例如
对于每个新成员,1 个命令将新成员添加到用户流,然后 1 个命令到组添加新成员信息。然后,一个简单的审计流程可以在启动/恢复时扫描不完整的成员资格分配,并作为定期数据质量检查。
-克里斯