Hello, World!
ASSUMPTIONS
Assume that,
- We have a DB with collections called orders and products.
- The documents in the orders (will be called as order from now on) collection contains references from the documents in the products (will be called as product from now on) collection, as an array of object IDs.
- The documents in the products collection has properties called name and price.
- name is an update insensitive property. (e.g. if a reference is given to the product, when the product is updated, it does not affect the order.)
- price is an update sensitive property. (e.g. if a reference is given to the product, when the product is updated, it causes a problem for the order. you lost the price of the product at the time of order is given.)
Also assume that we have the following sample data,
products
{_id: "p0", name: "apple", "price": 200}
{_id: "p1", name: "orange", "price": 500}
orders
{_id:"o0", orderNumber: 1, products: ["p0", "p1"]}
Assume that, the product apple’s price will be increased from 200 to 300, and orange’s price will be increased from 500 to 600.
products (after the update)
{_id: "p0", name: "apple", "price": 300}
{_id: "p1", name: "orange", "price": 600}
PROBLEM
- When the time the order is created, we sold apple from 200 and orange from 500.
- However after the update, it seems like we sold apple from 300 and orange from 600 which is totally incorrect.
Obviously, we can create another collection for keeping that change. However, when we have collections with documents that have a lot of properties we never know which property will be update sensitive in the future…
To overcome this problem, I find 2 solutions.
1- You hardcode the update sensitive data inside.
products
{_id: "p0", name: "apple", "price": 200}
{_id: "p1", name: "orange", "price": 500}
orders
{_id:"o0", orderNumber: 1, products: [{_id: "p0", "price": 200}, {_id: "p1", "price": 500}]}
products (after the update)
{_id: "p0", name: "apple", "price": 300}
{_id: "p1", name: "orange", "price": 600}
In this solution, if name becomes update sensitive in the future, since you do not hardcoded it before, you can never know the value at the time of the order is created. That’s why I tried to find my 2nd solution.
2- For each collection foo that may have documents with update sensitive properties, we create another collection fooRef which will only have 2 properties _id and currentVersion. _id as you may guess, and currentVersion is also object ID which points to the current version of the document in foo. Also the documents in the collection foo will have a property version.
products
{_id: "p0", version: "0", name: "apple", "price": 200}
{_id: "p1", version: "0", name: "orange", "price": 500}
productsRef
{_id: "pr0", currentVersion: "p0"}
{_id: "pr1", currentVersion: "p1"}
orders
{_id:"o0", orderNumber: 1, products: ["p0", "p1"]}
products (after the update)
{_id: "p0", version: "0", name: "apple", "price": 200}
{_id: "p2", version: "1", name: "apple", "price": 300}
{_id: "p1", version: "0", name: "orange", "price": 500}
{_id: "p3", version: "1", name: "orange", "price": 600}
productsRef (after the update)
{_id: "pr0", currentVersion: "p2"}
{_id: "pr1", currentVersion: "p3"}
Now, you can reach anything anytime. But this time, each time you update a document with a update sensitive property, you will create an additional record. This will increase the data size. Also, there will be records that you will never use and need.
CONCLUSION
What I am asking you is, maybe there is another solution I can’t figure out or maybe there is a best practice for this kind of problems.
Thanks in advance for the help…