Cqrs 在使用CQR的事件源中,应如何实施带条件的搜索

Cqrs 在使用CQR的事件源中,应如何实施带条件的搜索,cqrs,event-sourcing,Cqrs,Event Sourcing,假设我需要查询符合给定条件的所有实体。我最大的困惑是数据应该从哪里获取。我想我们有两种选择,要么查询事件存储本身,要么询问其他投影存储解决方案(不知道-可能是一些DB或什么)。这可能取决于处理的事件数量。实施情况如何 直接询问事件存储,我们将查询所有实体,然后在应用程序中过滤它们 使用DB,我们将只查询底层表,该表是针对特定条件搜索的泰勒表 性能怎么样 在事件存储中,最好的方法可能是创建一些快照,但不确定如何列出复杂的所谓“聚合”。在DB中,我们将拥有与事件几乎相同的行数,这将导致广泛的DB优化

假设我需要查询符合给定条件的所有实体。我最大的困惑是数据应该从哪里获取。我想我们有两种选择,要么查询事件存储本身,要么询问其他投影存储解决方案(不知道-可能是一些DB或什么)。这可能取决于处理的事件数量。实施情况如何

  • 直接询问事件存储,我们将查询所有实体,然后在应用程序中过滤它们
  • 使用DB,我们将只查询底层表,该表是针对特定条件搜索的泰勒表
  • 性能怎么样


    在事件存储中,最好的方法可能是创建一些快照,但不确定如何列出复杂的所谓“聚合”。在DB中,我们将拥有与事件几乎相同的行数,这将导致广泛的DB优化。更不用说,这个数据库可以随时删除和填补再次这是我完全无法想象的。我是否做对了事情,还是完全偏离了轨道?

    事件来源:是一种开发应用程序的方法,其中所有信息都作为事件持久化。有关更多信息,请参阅

    示例:如果我们正在开发银行软件,我们存储的事件如下所示

    • 用户1,交易日期:100,参考号:“xyz”,日期:2018年10月11日
    • 用户1,交易:-100,参考号:“xyza”,日期:2018年10月18日
    • 等等
    现在,如果用户1想要借记他/她的帐户,那么我们从他/她的流中提取所有事件并重播以获得余额。如果他/她有足够的余额,我们通过添加一个借记事件借记他/她的帐户

    这个过程需要一点时间,通常只有在需要写入系统时才进行(写入比大多数系统中的读取更不常见)。虽然这需要一点时间,但它给了我们审计能力、安全性和运行分析的好处

    事件源系统的难点在于查询。如果我们需要获得一个在一个季度内存款超过10000个单位的用户列表,那么这将是困难和耗时的,因为我们需要重播每个用户流。为了解决这个问题,我们可以使用CQR

    CQRS:是一种软件开发模式,其中写入由一个应用程序完成,读取由另一个应用程序完成。提供更多信息。写应用程序和读应用程序可以相互通信(可以通过消息传递)。read应用程序可以维护自己的数据库,并以便于查询的形式存储信息。因此,当读取应用程序获取消息时,它会转换适合自己的db模式的消息并存储它

    读应用程序最终(可能在几秒钟内)将与写应用程序保持一致。read应用程序将能够非常快速地处理查询,因为它的数据库模式是为它设计的

    现在回答您的问题:

    • 在写应用程序中更新数据需要一些时间。在任何更新之前,写入应用程序将重放所有事件(或快照后的事件)。只要骨料很小,我们采用适当的快照技术,性能就不错
    • read模型有自己的数据库,模式设计适合查询。很多时候,我们并不担心读取数据库中的冗余数据。这是为了使查询更快
    • 我们可以决定抛出读应用程序(模型)数据,并以另一种形式重新构建它,以适应新的查询,因为事实的来源是存储在写应用程序(模型)中的事件
        你还没有对CQR有正确的认识。CQRS的C用于仅更新数据的命令。它们使用事件存储中的事件实例化内存中的实体,进行适当的更改,然后将这些更改存储回事件存储。此端不适用于临时查询。将命令端视为只允许通过主键访问的数据

        读取端是查询具有特定属性的所有实体的地方。读取端由特殊代码构建在DB(不是事件存储)中,该代码侦听事件存储并在读取端DB中添加/更新行,以使其保持最新。请注意,读取端DB不是第三正常形式–数据经常重复,外键很少

        因此,虽然在技术上可以查询大多数事件存储的特定属性,但这很笨拙,因为这不是它们的设计目的。要获取对象集合,请查询读取端

        浏览一个典型示例

      • 用户到达您的站点并单击按钮以查看蓝色T恤的列表。您可以使用Type=“TShirt”和Color=“Blue”在读取端查询所有库存实体,并将此列表返回到用户屏幕,其中包含库存数量的计数器
      • 用户点击一件t恤,您可以在阅读端查询t恤和图片的详细信息。向用户显示使用该信息的屏幕
      • 用户将t恤添加到购物车中。执行AddItemToCart命令,该命令创建CartCreated事件,然后是ItemAddedToCart事件,然后是InventoryDecremented事件
      • 读取端订阅事件源并查看这些事件,因此会相应地更新其表
      • 第二个用户进来时也想要一件蓝色t恤,但她看到库存现在是0,因为前一个用户得到了最后一件。所有这些信息仅来自读取端数据库,而不是事件源(命令端)
      • 如果你在脑海中把这两方面分开,那么很多关于如何实现某件事的问题就会消失。

        因此,万一我