Document based modelingAuctions
We recently had a client with a similar model, and I thought that this would be a good topic for a series of blog posts. For the purpose of this blog posts series, I am going to be using EBay as the example. Just to be clear, this is merely because it is a well known site that most people are likely to be familiar with.
In our model, we have the following Concepts:
- Categories
- Products
- Auctions
- Bids
- Sellers
- Buyers
- Orders
We will start from what is likely the most confusing aspect. Products and Auctions.
A Product is something that can be sold. It can be either a unique item “a mint condition Spiderman comics” or it can be something that we have lots of “a flying monkey doll”. There is a big distinction between the two, because of the way the business rules are structured.
Once an Auction has been started, it cannot be changed. This include everything about this auction, pricing, shipping information, product information, etc. But a Product may change at any time (maybe I now have the flying monkey in red and green, instead of the original red and yellow). That leads us to conclude that we actually have two instances of the Product in our domain. We have the Product Template (mutable, can change at any time) and with have the Auctioned Product (immutable).
That realization leads me to the following model for products and auctions:
{ "Name":"Flying Monkey Doll", "Colors":[ "Red & Yellow", "Blue & Green" ], "Price":29, "Weight":0.23 } { "Quantity":15, "Product":{ "Name":"Flying Monkey Doll", "Colors":[ "Blue & Green" ], "Price":29, "Weight":0.23 }, "StartsAt":"2011-09-01", "EndsAt":"2011-09-15" }products/1 auctions/1
As you can see, the Auction is going to wholly own the product. Any change made to the product will not be reflected in the Auctioned Product. This has the advantage that we need only a single document load in order to show the auction page.
Another option would be to use the versioning bundle to do that, so we would have this:
{ "Name":"Flying Monkey Doll", "Colors":[ "Red & Yellow", "Blue & Green" ], "Price":29, "Weight":0.23 } { "Name":"Flying Monkey Doll", "Colors":[ "Blue & Green" ], "Price":29, "Weight":0.23 } { "Quantity":15, "Product": "products/1/versions/1", "StartsAt":"2011-09-01", "EndsAt":"2011-09-15" }products/1 products/1/versions/1 auctions/1
The versioning bundle ensures that we can get immutable views of our documents, so we can safely reference the product by its id and version.
That is it for now, on the next post, we will deal with how to work with bids.
More posts in "Document based modeling" series:
- (30 Sep 2011) Auctions & Bids
- (06 Sep 2011) Auctions
Comments
Hi Ayende, if the auction cannot be changed after it's begining, for the sake of simplicity wouldn't be better to maintain the product inside the auction? In this case I'm talking only about performance. I don't think about a product maintenance because normaly in this kind of site they don't care about the products, the client (user) manage this and normally loss the information about the "version" of the products.
(I know that the code will ensure that a referenced product can't be deleted or that every change will create a new version of the product or something like that)
Now we are talking! You did not mark your soultion with so popular these days DDD tag, nonetheless it's very close to the aggregating and storing references to entities. Nice showing the way, of solving one of the most common scenarios with references to the historical versions of entities. I find the versioning bundle great addition to the pool of possible solutions.
Winston, That is exactly what we are doing in the first alternative.
Hmmm... I have a similar model for a silent auction solution I built internally however how would you suggest an alteration to handle individual items. Quantities are fine for bulk purchases where all items are the same, but what about tracking bids on each item and each item in the bulk collection having it's own attributes.
Two examples. First I have 15 Flying Monkey Dolls. So I need to handle bids separately on all 15 of them because not everyone is going to pay the same price. (I think you might handle this in your bids post).
The other example is 15 individual prices for each item (from the auction side, not the bid). So I have 15 Flying Monkey Dolls in stock that I want to put up for auction but I want to set the price for 5 of them at $10, 5 of them at $15, and 5 of them at $20 (maybe I'm conducting a social experiment to see if people flock to the lowest priced item first).
Does this change the model(s) at all?
Bil, I would probably use separate Auctions for each of those items / price points
Comment preview