Event Source Tracing (6): Query the Event Store through Projection

Original link: https://teddy-chen-tw.blogspot.com/2022/07/6projectionevent-store.html

June 30 22:15~23:38

截圖 2022-06-30 下午10.28.48

▲Figure 1: Projections screen of EventStoreDB

foreword

Applying Event Sourcing in domain-driven design, the data of an Aggregate instance is stored to the event stream of the Event Store through the Repository, and a single Aggregate instance is used as the basic unit when it is read. But this is obviously not enough to meet the needs of most systems to query data. Before further applying CQRS to solve the query problem, this episode first introduces how to use the Event Store, which is mainly used for writing, as a query database. .

***

Projection

Next, Teddy will take EventStoreDB as an example to explain how to use Event Store to query data. Teddy mentioned before that Aggregate-ID is generally used as an event stream file to store the domain events of Aggregate instance in EventStoreDB . For example, a Tag Aggregate instance whose id is equal to 4cc11cc7-707b-476a-801c-1b6a22a69169, then its domain events will be stored in the event stream named Tag- 4cc11cc7-707b -476a-801c-1b6a22a69169 in EventStoreDB.

In EventStoreDB , in addition to this event stream representing Aggregate instance, the system also has some special event streams:

  • $all : All events generated by the system can be found in the $all stream.
  • System projections : The system automatically “projects” the stream generated according to some built-in specific conditions. The more commonly used ones are:
    • By Category ($ce-) : Category is the Aggregate Type, and EventStoreDB will project events of different Aggregate Types into the $ce-[Aggregate] stream. For example, all Tag instance events can be read from the $ce-Tag stream.
    • By Event Type ($et-) : Project each event type into an event stream, for example, you can read all TagEvents$TagCreated field events from the $et-TagEvents$TagCreated stream.

***

Use Projection to query data

The following uses querying how many tags a board has as an example to illustrate how to use projection to query data.

In ezKanban, the tag and the board maintain a one-way dependency on the boardI on the tag. The board does not know how many tags it has, so it cannot get the number of tags on the board from the boardrepository. The basic TagRepository can only find a certain Tag based on the tad id, and cannot find all the tags belonging to a certain Board.

Referring to Figure 2, to find out how many tags a board has, just:

  1. Read all events from the $et-TagEvents$TagCreated stream, and then use the boardId on the event as a filter condition to find a List<TagCreated> to represent the IDs of all tags on a board.
  2. Run a for each loop and call TagRepository according to the List<TagCreated> found in step 1 to find all the tags in all the boards.

截圖 2022-06-30 下午11.05.32

▲Figure 2: DomainEventTypeMapper interface

***

Pros and cons of EventStoreDB Projection

Projection of EventStoreDB is a very powerful function, which allows the database originally mainly used to support Write Model to be used as “Read Model database” at the same time . Of course, this View Model still retains the feature of Event Sourcing in essence, that is to say, to get the “current state” of the domain object, it is necessary to read all the domain events in the Read Model and replay them. The speed may not be as fast as after using CQRS, using the NoSQL database as the Read Model can directly read the entire Read Model into the memory as long as the next query condition.

However, the so-called “slow (or very slow)” may not be as slow as people think, and it still depends on the actual situation of the application. Maybe this speed is acceptable in many cases. After all, using the Projection of EventStoreDB directly can easily generate the Read Model, and applying CQRS requires additionally writing a Projector to project the Read Model on the read-side database, which is a lot of work.

Another point to note is that EventStoreDB uses an asynchronous way to project these Projections, which means that the state synchronization between these Projections and the originally written domain events is eventual consistency . Therefore, you may find out why sometimes the domain events have been written into the database, but the related domain events cannot be read in Projection.

***

next episode preview

After introducing the basic write and read operations of Event Sourcing, the next episode discusses how to avoid data conflicts through optimistic locking when multiple people read and write data at the same time.

***

Youzo’s inner monologue: You will not be used to the fact that you can’t use Select to query data.

This article is reprinted from: https://teddy-chen-tw.blogspot.com/2022/07/6projectionevent-store.html
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment