在CQRS/ES世界的报道



我想我理解了ES + CQRS背景下读取模型的思想(如果不理解请纠正我)。然而,我仍然对在"严肃"报道中使用它有一些疑问。假设我使用关系数据库和一些ORM来简化我的读模型。一个基本的"summary stats read model"可能是这样的:

 class SummaryStats1
    {
    public Guid TypeId { get; set; }
    public string TypeName { get; set; }
    public Guid SubTypeId { get; set; }
    public string SubTypeName { get; set; }
    public int Count { get; set; }
    }

给定一个事件:

TypeId = 3acf7d6f-4565-4672-985d-a748b7706a3e
TypeName = Bla1
SubTypeId = 41532aa1-f5d1-4ec4-896b-807ad66f75fc
SubTypeName = Bla2

归一化器将:

(1)检查是否存在上述组合的实例(由TypeId, TypeName, SubTypeId, SubTypeName定义)(2)如果没有实例,它将创建一个实例并设置Count为1。如果有,则将Count增加1。

这是可接受的报告方法吗?我想可以对这种非规范化的数据结构(用于过滤和其他sql"投影")运行非常有效的选择:

SELECT  TypeName, Sum(Count) FROM SummaryStats1 GROUP BY TypeName

CQRS/ES专家会同意这一点吗?这是做事的"方式"吗(即创建这些专用的报告读取模型)?任何参考源代码/真实的例子将非常感激。

这是可接受的报告方法吗?

还是报告方法当然取决于您的需求,但总体思路是正确的。

总结:

您根据来自您的领域的事件生成读取模型(有时使用的官方术语是Eager read Derivation)。

读取模型可以是任何你想要的(sql, redis, mongo等)。无论什么都可以使您的查询具有高性能。例如,在你的例子中,没有理由你不能有两个读模型来更有效地执行你的查询(尽管你所描述的对于大多数情况可能已经足够了):

  1. 描述的sql视图
  2. 一个由typeName分组的预聚合视图,这样你就不必在每次查询时都进行分组(而是在规范化器中计算分组)。

简而言之,在如何构建读模型上没有正确或错误的方法。其美妙之处在于,您可以完全自由地以任何您想要的方式(基于您设想的查询模式和性能瓶颈)对您的读模型进行建模,而不必考虑这些模型如何影响写(仅仅因为它们不会,因为cqrs将读和写分开)

将事件源与CQRS结合使用提供了更好的可能性,即通过重播事件源中的过去事件来创建新的readmodel并填充数据。

只是一些额外的例子,可能被认为是你的数据的'读取模型':

  • 使用Redis的INCR视图(这是您似乎描述的替代方案)
  • 一个Elasticsearch/Solr搜索索引
  • 用于按键快速查找的KV-store/索引。

想法是,这些"读模型"/视图总是保持最新(最终一致)推送更新事件给他们(通常是通过pubsub)

更多好的阅读,请看这个问题的答案和链接:使用CQRS的读端实现方法

相关内容

  • 没有找到相关文章

最新更新