I have a CosmosDB document that models something in my problem space -- a Car for our purposes. It currently has a bunch of properties relating to the model, color, year manufactured, etc. I would like to treat the Car as a DDD Aggregate, including public methods for mutating the state of the object and for delegating methods calls to other objects referenced directly by the Aggregate (within the same document). I'm aware that in a better DDD implementation I would have data model(s) distinct from the domain model(s) with mapping functions between them, but its been a hard enough sell to treat the document as a full fledged Aggregate. The preferred direction by the team is to treat the document in an anemic fashion, with Aggregate methods appearing in the Application Service, which makes testing of Aggregate logic more difficult. Is there any downside to including the Aggregate logic directly in the document?
1 Answers
Storing aggregates or utilizing Materialized Views in documents on domain data in Cosmos DB is quite common as it reduces or eliminates the need for frequently run, but often expensive queries.
For instance, in a simple ecommerce scenario, it is more efficient to have the order total in the order header and fetch via point read ReadItemAsync() rather than doing a query to fetch and Sum all the order items. Another scenario would be where you need to keep a running total for sales in all categories for the day. In this scenario you have a single document that has categories with any sales for the day. As each order occurs, the insert operation for each item in the cart triggers Change Feed which does a point read on the aggregate document and upserts the category total, incrementing it by the new sold item. Then instead of querying all sales for the day which gets progressively more expensive as orders grow, you simply issue a point read to get the totals which would be a 1 RU operation.