Working with projections that create streams - best practice?

Looking for “best practice” advice related to projections:

My teammate is working on a projection that creates a derivative “header” stream for each Widget entity’s stream. This is because Widgets have tons and tons of events but some of the can be considered “header level” and when building a model of a Widget in memory (to, say, execute a command on it), it is often only necessary to scroll through the header-level events.

Here is the projection:

fromCategory(‘widget’)
.when({
“WidgetCreated”: function(state, event) {
linkTo(‘widget.header-’ + event.data.id, event);
},
“WidgetAltered”: function(state, event) {
linkTo(‘widget.header-’ + event.data.id, event);
},
“WidgetDeleted”: function(state, event) {
linkTo(‘widget.header-’ + event.data.id, event);
}
})

``

So for example, if we have stream named “widget-e8d55c44-d0c7-430d-a187-33e5040fe5c1”, this projection would create a co-stream widget.header-e8d55c44-d0c7-430d-a187-33e5040fe5c1 that would contain only what we deem are header-level events for that widget. So for example we definitely consider WidgetCreated and WidgetDeleted as header events, but not WidgetDoodadTwisted or WidgetThingamabobRecalibrated.

THE PROBLEM

My teammate, in testing and debugging her projection, found it necessary to alter the code and rerun, possibly she also deleted and recreated it under a different name, not sure. I think you can already guess we got the old “Multiple projections emitting to the same stream detected” error.

I know the low-level reason why this is happening, but it’s making me wonder: are we misusing projections? If it’s this difficult to play with projection code until we get it right, and then have a mess of projection-created-but-still-resident streams to deal with?

Right now she just has one single test widget stream, but someday we’ll have hundreds. Impractical to remove all “widget.header-” streams every time we need to fiddle with the projection, just to avoid that error message.

ALTERNATIVE - should we be implementing this “projection” outside Event Store here?

In our Node service that uses Event Store we have event handlers that subscribe to ES streams and populate a query database (standard event sourcing / CQRS here). Should we be using this mechanism to build the “header” streams instead of locking horns with ES here?

Its been added that deleting a projection will delete all the streams
that it created.

Oh good! I was hoping you’d move in that direction. What version is that true as of? We are working with 3.7 now due to another issue.

https://github.com/EventStore/EventStore/releases/tag/oss-v3.8.0 See #970
Note the projection must originally be created in this version or
higher for the feature to work.

I don’t see any documentation in general for how to upgrade an existing database (by the way). Given that we’re using 3.7 until our “0.0.0.0” issue (linked above) can be resolved, so we’re creating projections at that version level.

Install the new version and start it. There is no upgrade process. If
there is one it would be between major versions (we use sem ver). For
a cluster you upgrade one node at a time.