Back to Kurrentdb

Projections tutorial

docs/server/features/projections/tutorial.md

26.1.06.5 KB
Original Source

Projections tutorial

Follow the steps below to learn how to create a user defined projection.

Add sample data

Download the following files that contain sample data used throughout this step of the getting started guide.

Add the sample data to four different streams:

@code

Create your first projection

::: tip Next steps Read this guide to find out more about the user defined projection's API. :::

The projection counts the number of 'XBox One S's that customers added to their shopping carts.

A projection starts with a selector, in this case fromAll(). Another possibility is fromCategory({category}) which this step discusses later, but for now, fromAll should do.

The second part of a projection is a set of filters. There is a special filter called $init that sets up an initial state. You want to start a counter from 0 and each time KurrentDB observes an ItemAdded event for an 'Xbox One S,' increment the counter.

Here is the projection code:

@code

You create a projection by calling the projection API and providing it with the definition of the projection. Here you decide how to run the projection, declaring that you want the projection to start from the beginning and keep running. You can create a projection using the Admin UI by opening the Projections tab, clicking the New Projection button and filling in the details of your projection.

You can also create projections programmatically. Pass the projection JSON file as a parameter of your request, along with any other settings:

@code

Query for the projection state

Now the projection is running, you can query the state of the projection. As this projection has a single state, query it with the following request:

@code

The server will send a response similar to this:

@code

Append to streams from projections

The above gives you the correct result but requires you to poll for the state of a projection. What if you wanted KurrentDB to notify you about state updates via subscriptions?

Output state

Update the projection to output the state to a stream by calling the outputState() method on the projection which by default produces a $projections-{projection-name}-result stream.

Below is the updated projection:

@code

To update the projection, edit the projection definition in the Admin UI, or issue the following request:

@code

Then reset the projection you created above:

@code

You should get a response similar to the one below:

@code

You can now read the events in the result stream by issuing a read request.

@code

And you'll get a response like this:

@code

The number of items per shopping cart

The example in this step so far relied on a global state for the projection, but what if you wanted a count of the number of items in the shopping cart per shopping cart.

KurrentDB has a built-in $by_category projection that lets you select events from a particular list of streams. Enable this projection with the following command.

@code

The projection links events from existing streams to new streams by splitting the stream name by a separator. You can configure the projection to specify the position of where to split the stream id and provide a separator.

By default, the category splits the stream id by a dash. The category is the first string.

Stream NameCategory
shoppingCart-54shoppingCart
shoppingCart-v1-54shoppingCart
shoppingCartNo category as there is no separator

You want to define a projection that produces a count per stream for a category, but the state needs to be per stream. To do so, use $by_category and its fromCategory API method.

Below is the projection:

@code

Create the projection with the following request:

@code

Querying for the state of the projection by partition

Querying for the state of the projection is different due to the partitioning of the projection. You have to specify the partition and the name of the stream.

@code

The server then returns the state for the partition:

@code

Configure projection properties

You can configure properties of the projection by updating values of the options object. For example, the following projection changes the name of the results stream:

@code{2}

Then send the update to the projection:

@code

::: tip You can find all the options available in the projections API documentation. :::

Now you can read the result as above, but use the new stream name:

@code

Query running projections

You can also query the state of all projections using the HTTP API.

@code

The response is a list of all known projections and useful information about them.

@code