EventStore Projections when to use them

1.7k views Asked by At

I've been looking at Event Store for a little while now and one thing that stumped me is when should one consider writing a projection? Is it common practice to create a flattened projection?

The setup here is using a stream per aggregate

For example, lets say I have 2 events that look like this:

public class OrderPlaced
{
    public OrderPlaced(string reference, Currency currency, Amount amount)
    {
        ...
    }

    public string Reference { get; }

    public Currency Currency { get; } //Custom type

    public Amount Amount { get; } //Custom type
}

public class OrderCompleted
{
    public OrderCompleted(string reference)
    {
        this.Reference = reference;
    }

    public string Reference { get; }
}   

I have the following query:

fromCategory('MyCategory')
  .whenAny(function(s, e) {
      linkTo("Foo", e);
  })

The above doesn't do a great deal and only aggregates all the streams into a singular. Is it possible to project a view that is more flat, for example into something like this? Perhaps I got my wires crossed but apparently using emit can achieve this?

{
    string Reference;
    string CurrencyCode;
    decimal PayingAmount;
}

My thinking is, once I have written to the stream I can guarantee the aggregate is in a valid state and thus for any interested parties I should only expose the fields these processes require. Is projecting a simple model (a de-nomarlized view) the correct thing to do..

The above is a trivial example, but you can imagine an aggregate being a little more complicated.

If I have missed anything or further clarification is needed then please comment and I can add.

1

There are 1 answers

0
Alexey Zimarev On

You are looking for a standard event category projection.

It emits linked events to steam that are called ´$ce-´. The category there is your object type.

For example, your aggregate type is Order, and you write events OrderCreated, OrderLineAdded, etc to streams with names Order-1, Order-2, where 1 and 3 are your aggregate root ids. Then, the $ce-Order stream will contain all events for all aggregates of that type.

Have a look at the standard projections documentation.

Usually this is exactly the way to create read-side projections - by creating a catch-up subscription on category streams and updating the read model accordingly.

In order to run projections, you need to use --run-projections=all –-start-standard-projections=true to see it working.