Event Store as denormalization engine

I recently wrote a post called Data Denormalization Is Broken and am researching various systems that could implement a “denormalization engine”.

Would it be possible to define a projection to automatically update a value like User.numUnreadRooms shown in the post, which involves a nontrivial query?

I just looked into CouchDB, and unfortunately its MapReduce system lacks the expressive power to help me in this use case.

I’m more optimistic about Event Store but I’m not sure. I’ll appreciate if you guys can tell me whether it’s a feasible thing to hope for.

Actually its trivial.

Let's assume that you have events for chat messages and you have an
event for "userRead" and userJoined.

fromCategory('chatroom').
    foreachStream().
    when({
           ChatMessage : function(s,e) {
                 for(key in s){
                      s[key]+=1
                 }
           },
           UserRead : function(s,e) {
                 s[e.userName] -= 1
           },
           UserJoined : function(s,e) {
                 s[e.userName] = 0
           }
    })

You could also do this quite easily in an external read model.

btw: ^^^ is typed in gmail so is not promised to compile :slight_smile:

I should add ^^^ is also a naive approach you could obviously optimize this.

Thanks Greg. I’m a fan of your talks and would like to start doing some Event Sourcing in my projects.

“You could also do this quite easily in an external read model.” - can you elaborate?

Also, I’m new to Event Store so I’d appreciate seeing how to aggregate the number of unread rooms.

Also, I notice this approach is imperative / trigger style, meaning we have to spread out the code for a computed value across all the dependencies where it’s computed from. Is there a more declarative / materialized view / Functional Reactive Programming style approach?

“You could also do this quite easily in an external read model.”

I believe what he means is creating one stream for all the relevant events, e.g.

fromCategory('chatroom')
  .whenAny(function(s,e) {
    linkTo('chatrooms',e);
  });

and then simply subscribing to the “chatrooms” stream.

It is them up to you to do the equivalent of Greg’s code, but, say, in your Java or .NET - and put the results into some local database, like MySQL or what-not.