如何从事件存储中查询多个聚合?

时间:2021-02-12 16:59:42

标签: c# .net cqrs event-sourcing

假设我通过事件溯源存储汽车。我有一个 CarAggregate,它可以使用汽车存储库正确保存/加载事件:

CarAggregateRepository
{
   CarAggregate GetById(Guid id)
   {
      var events = EventStore.LoadEventsById(id);
      var carAggregate = new CarAggregate(id);
      carAggregate.ApplyEvents(events);

      return carAggregate;
   }

   void Save(CarAggregate car)
   {
      EventStore.StoreEvents(car.Id, car.UncommittedEvents);
   }
}

我现在想要一种方法来查找匹配特定查询的汽车,例如,梅赛德斯制造的所有汽车:

List<CarAggregate> Find(string manufacturer)
{
   // What goes here?
}

我能想到的唯一方法是:

  1. 加载所有事件
  2. 建立所有聚合的列表
  3. 筛选具有匹配制造商的列表

这肯定是非常低效的,因为我最终可能会从事件存储中加载数十万个单独的事件?这是大量的数据传输。此外,加载的许多这些聚合可能用于甚至不是 CarAggregates 的东西。也许它们是 UserAggregates,其事件也存储在同一个事件存储中?

我一定是遗漏了什么。如何列出与我的查询匹配的所有 CarAggregates?

1 个答案:

答案 0 :(得分:2)

<块引用>

//这里有什么?

通常的答案是读取模型的接口在那里。

也就是说,您将有一些逻辑从您的事件存储中获取事件,并从中创建/更新一个报告,其中包含您在某种形状/数据结构/持久性存储中所需的信息,使查询更容易(因此:CQRS ).

一个常见的答案是有一个订阅事件存储的进程,也就是说它侦听更改,查询存储以获取新事件的副本,然后更新某些 RDBMS 中的行,您可以使用它生成您的报告。

您可以将报告视为事件存储中信息的缓存副本。信息会有点陈旧(这部分取决于您愿意为减少延迟花费多少)。

您可以检查您的事件存储,然后遍历所有事件直到该检查点,找出哪些汽车与您的查询匹配,但延迟很糟糕,并且需要大量重复性工作。因此,我们在后台执行这项工作,您的查询不是针对“现在”事件存储的外观,而是针对最近报告的检查点时事件存储的外观。