Event Store Projections – Counting events of a specific type

Our first Event Store Projections example simply counts the number of events of a specific type. Pretty mundane, I know, but it’s a good place to start.

Projection-MeasurementRead

In this example, the projection will take all MeasurementRead events from all streams and increase a counter in its global state for each one. The end result is a global state containing the number of MeasurementRead events.

Projection-MeasurementReadCounter-Events

JavaScript implementation

The projection logic is implemented in a self-revealing module. This pattern allows us to decide which methods of a module should be accessible from outside, much like creating a class with public and private methods. The pattern is probably overkill for this projection, since it only has public methods, but it allows us to create unit tests for its logic:

The init method initializes the state for the first time by setting the count property to 0. The increase method increases the count property by 1 when called.

This module is instantiated once globally and then referenced from the projection’s definition:

The fromAll definition tells the engine that the projection’s events come from all streams. Inside, we delegate $init and MeasurementRead to our counter module implementation. The $init field defines the method that initializes the projection’s state, and the MeasurementRead field defines that all MeasurementRead events are to be handled by the counter.increase method.

producesResults is set to true so that the projection’s state is stored in a stream. This allows us to subscribe to projection state updates without polling and use the output of the projection as input for other projections, as I’ll demonstrate later. In the future, we can replace this with the outputState method.

Testing the projection

I used Jasmine to test this logic. Jasmine is a really nice BDD framework for testing JavaScript code that encourages developers to write readable test scenarios:

ALSO READ  Event Store Rest API Basics (Node.js)

The test contains two cases: the first one verifies the initial state of the projection, and the second one verifies the count property is increased by 1 for each call of the increase method. The first two lines define the referenced JavaScript files, which enables Intellisense in Visual Studio and allows R# to run the tests from your IDE.

Querying the results with the Client API

To read the value of the projection, we use the getState method of the ProjectionsManager class.

Since we specified that the output of the state should be stored in a stream, we can subscribe to event updates without polling:

Source code

A working project for this example can be found on github: https://github.com/tim-cools/EventStore-Examples

Event Store Projections by Example

This post is part of a series:

  1. EventStore Client API Basics (C#)
  2. Counting events of a specific type
  3. Partition events based on data found in previous events
  4. Calculating an average per day
  5. The irresponsible gambler
  6. Distribute events to other streams
  7. Temporal Projection to generate alarms
  8. Projection in C#

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *