Thank you for the thorough answer. That is good info.
As far as it being in the docs… On this page ( http://geteventstore.com/docs/projections.html ), under view/edit, it only mentions GET and PUT. POST is mentioned under creation (also enable/disable). Mentally, I wasn’t connecting a create with an update + rebuild.
I’m on the fence about the basic read model (if you were to add indexing). It would be nice to get rid of another technology (read model DB) and would potentially save a lot of denormalizer code. But, it being unexplored country, I wouldn’t even know where the rough edges are or how to design around them.
Projections are not heavily documented with reason (they aren’t actually 100% done yet!).
For rebuilding. It depends whether you post or put to the url. That actually is documented
“So what exactly should projections be used for? Are we supposed to make a filtered/custom-partitioned projections for denormalizers? Or use the projection directly as a read model? (since the events can be folded into a JSON state object) Or use them as a message bus queues grin ?”
Now what they are for …
Projections are a form of read model and solve very easily a certain problem that is very hard to solve in other systems. In particular the library supports JavaScript for Complex Event Processing. I know lots of fancy words. Let’s try a concrete example (I am writing a blog post series now on it so let’s use one from there …).
In almost all financial systems there exists a piece of code that builds “candlesticks” for charts. A candlestick represents over a time period 4 price points (the first price, the last price, the highest price, and the lowest price) so we could have 1 minute candlesticks (open, close, high, low … one per minute). Could you write that query for me in SQL server? select * from ticks where select * from ticks … ouch This is a temporal correlation query (its CEP). This is the exact type of problem that projections are meant to solve (and you will find them much more often than you think!).
That system (building candlesticks) is a huge amount of work to do. Not because of the logic of building candlesticks but because of all the other junk that needs to be built into the system (failovers, high availability, clustering, etc). What if I could just write the candlesticking logic in javascript and everything else were handled for me (clustering etc …). This is where projections are positioned. There is an entire category of problems they are very good at handling. They are not a replacement for having a read model, they are just a form of a read model (though we have talked about supporting indexing over the top of streams with data so you can also build a basic read model internally).
Let’s try another example. I have seen no less than 5 custom systems for doing reports off of nservicebus audit queues. Basically they ask three questions of the system.
“I want to see events at time X”
“I want to see events for user Y”
“I want to see events for correlationId C”
Now let’s try doing this with the event store. We would write an adapter to put the messages from nservicebus into the event store (as NServiceBusMessage). Now we would write 2 projections.
fromAll().when(‘NServiceBusMessage’ : function(s,e) { linkTo(e.username, e); });
fromAll().when(‘NServiceBusMessage’ : function(s,e) { linkTo(e.correlationid, e); });
Now if you navigate to /streams/{username} you have all of the messages for that user there, reporting system done (dev which is getting moved to master today even has ability to realtime view streams in browser or use whatever your favorite atom browsing tool is).
Where things really begin to shine though is when we do more so CEP like candlesticks above. Let’s say you have a question about your system. When event X happens then event Y is Z more likely to happen? We could easily write a one off projection for this!
HTH,
Greg
p.s. we have more docs coming on projections (including a blog post series) the lack is deliberate. If you look at the latest builds they are disabled by default and marked as “experimental”