Are projections good for this?

Hello Community! :slight_smile:

Do the projections have enough power to solve this?

I have two event types:

A: {	
	Message,
	CorrelationId
}

and

B: {	
	ParentCorrelationId,
	CorrelationId
}

I would like for each event A emit new event C:

C : {
	Message,
	ContextPath
}

where ContextPath is CorrelationId1/CorrelationId2/CorrelationId3/… computed from B (join) events.

For example, for sequence:

A: {Message: "something", CorrelationId: 1}
A: {Message: "something2", CorrelationId: 1}
B: {ParentCorrelationId: 1, CorrelationId: 2}
A: {Message: "something3", CorrelationId: 2}
A: {Message: "something4", CorrelationId: 1}
B: {ParentCorrelationId: 2, CorrelationId: 3}
A: {Message: "something5", CorrelationId: 3}
B: {ParentCorrelationId: 1, CorrelationId: 4}
A: {Message: "something6", CorrelationId: 4}

We should produce:

C: {Message: "something",  ContextPath: "1"}
C: {Message: "something2", ContextPath: "1"}
C: {Message: "something3", ContextPath: "1/2"}
C: {Message: "something4", ContextPath: "1"}
C: {Message: "something5", ContextPath: "1/2/3"}
C: {Message: "something6", ContextPath: "1/4"}

Is it possible with projections?

I think so, but are Events A and B on the same stream?
If your proejction montiros the stream(s) that A and B are written to.
Assuming correlationId would be you partition id?

Well, if you think it is possible, I will try to write a projection or a group of projections that do this.

Although I think it will not be easy to construct CorrelationId 1 / CorrelationId 2 / … path by sequential observation of events A and B with projection state that has constant size and not contain array of previous events.

As for your questions. Yes, I planned to have events A and B on the same stream, but if that helps, they can be on different streams.

“Assuming correlationId would be you partition id?” - are you suggesting using partitionBy() function?

Yeah, using partitions could solve this.
You only need to actually use partitionBy if you want to change the partition name.

For example, I have a projection which processes all my sales:

fromCategory("SalesTransaction")
    .foreachStream()
    .when({
            $init: function(s, e) {
                return initialiseState();
            },
            $any: function(s, e) {
				
            }
        });

This will create the partition for me (say I had a called SalesTransaction- d547edae2cd94d5a8eb4371045c79567)
You would only need to call byPartition() if you wanted to change the name of that.

Does that help?

Thank you for your response.
I’ve tried to solve mentioned problem using projections but I encountered big difficulties.
So I gave up and decided to use C# and separate program for this.
Projections are not for everything.
And there are strange restrictions, for example: why can’t two projections write to the same stream?

why can’t two projections write to the same stream?

It would mess up the checkpoint on the projection stream and give you non deterministic results in case of a database crash. Longer answer here: "Multiple projections emitting to the same stream detected" after recreating a projection