page_type | languages | products | name | urlFragment | description | ||
---|---|---|---|---|---|---|---|
sample |
|
|
Azure Cosmos DB design pattern: Document Versioning
|
document-versioning |
This example demonstrates how to implement document versioning in Azure Cosmos DB to track and manage historical versions of documents, such as orders in an eCommerce environment. |
Document versioning is used to track the current version of a document and store historical documents in another collection. Where schema versioning tracks the schema changes, document versioning tracks the data changes. This pattern works well when there are few document versions to be tracked.
This sample demonstrates:
- ✅ It showcases how to implement document versioning in Azure Cosmos DB to track and manage the current and historical versions of documents.
- ✅ The example illustrates the separation of current document versions stored in a
CurrentOrderStatus
collection and historical document versions stored in aHistoricalOrderStatus
collection. - ✅ It highlights the integration of Azure Cosmos DB change feed processor running as a .NET [BackGroundService] (https://learn.microsoft.com/dotnet/architecture/microservices/multi-container-microservice-net-applications/background-tasks-with-ihostedservice) capture and copy the versioned documents to the historical collection, enabling efficient tracking and management of document versions.
Some industries have regulations for data retention that require historical versions to be retained and tracked. Auditing and document control are other reasons for tracking versions. With document versioning, the current versions of documents are stored in a collection named to store the current documents. A second collection is named to store historical documents. This improves performance by allowing queries on current versions to be polled quickly without having to filter the historical results. The document versioning itself is handled at the application layer - outside of Azure Cosmos DB.
In this example, we will explore document versioning using orders in an eCommerce environment.
Suppose we have this document:
{
"customerId": 10,
"orderId": 1101,
"status": "Submitted",
"orderDetails": [
{"productName": "Product 1", "quantity": 1},
{"productName": "Product 2", "quantity": 3}
]
}
Now, suppose the customer had to cancel the order. The replacement document could look like this:
{
"customerId": 10,
"orderId": 1101,
"status": "Cancelled",
"orderDetails": [
{"productName": "Product 1", "quantity": 1},
{"productName": "Product 2", "quantity": 3}
]
}
Looking at these documents, though, there is no easy way to tell which of these documents is the current document. By using document versioning, add a property to the document to track the version number. Update the current document in a CurrentOrderStatus
container and add the change to the HistoricalOrderStatus
container. In the project here, you can see how to implement the document versioning feature with the following components:
- A website that allows you to create orders and change the order status. The website updates the document version and saves the document to the current status container.
- An Archiver Service implemented as a .NET Background service that itself implements Cosmos DB Change Feed that sees when the Order Helper updates the order and copies the versioned document to the historical status container.
The demo website includes links to update the orders to the different statuses.
Open the application code in GitHub Codespaces:
git clone https://github.com/Azure-Samples/cosmos-db-design-patterns/
Directions installing pre-requisites to run locally and for cloning this repository using Terminal or VS Code
You need to configure the application configuration file to run these demos.
-
Go to resource group.
-
Select the Serverless Azure Cosmos DB for NoSQL account that you created for this repository.
-
From the navigation, under Settings, select Keys. The values you need for the application settings for the demo are here.
While on the Keys blade, make note of the URI
and PRIMARY KEY
. You will need these for the sections below.
- Open the website project and add a new appsettings.development.json file with the following contents:
{
"CosmosDb": {
"CosmosUri": "",
"CosmosKey": "",
"Database": "DocumentVersionDB",
"CurrentOrderContainer": "CurrentOrderStatus",
"HistoricalOrderContainer": "HistoricalOrderStatus",
"PartitionKey": "/CustomerId"
}
}
-
Replace the
CosmosUri
andCosmosKey
with the values from the Keys blade in the Azure Portal. -
Save the file.
- In Codespaces or locally, navigate to the
website
folder, start the website with:
dotnet run
Navigate to the URL displayed in the output. In the example below, the URL is shown as part of the info
output, following the "Now listening on:" text.
- With the web app running, create 5-10 orders with the website.
This is what the website will look like when starting out:
The Create New Orders form will create orders without the DocumentVersion property. Enter a number in the Number to create text box, then select Submit. This is how the new order appears on the website:
This is what the new order looks like in Azure Cosmos DB. Notice that the DocumentVersion
property is absent.
The Archive Service
in the web application is working directly with a VersionedDocument
type, so it will carry the DocumentVersion
field into the HistoricalOrderStatus
container. For new documents, this will assume the DocumentVersion is 1 when it isn't specified.
Unversioned documents will still show as document version 1 due to the VersionedOrder
C# class.
Select any of the links in the Links columns to change the status on the document.
As you advance the status of the orders, notice that the Document Version field increments. The document version numbering is managed by the application, specifically in the HandleVersioning()
function in the OrderHelper
class in the Services
folder.
You can query the CurrentOrderStatus
container in Data Explorer for the order number (OrderId
) and Customer Id (CustomerId
) and should only get back 1 document - the current document.
In this example, the previously shown document was fulfilled. Notice in the Azure Data Explorer results that the DocumentVersion
property is now a part of the document in CurrentOrderStatus
.
You can also query the HistoricalOrderStatus
container for that order number and customer Id and get back the entire order status history.
In this example, the previously shown document was fulfilled. Notice in the Azure Data Explorer results that the DocumentVersion
property is now a part of the document in CurrentOrderStatus
.
The NoSQL Document Versioning design pattern is used in NoSQL databases to manage different versions of documents efficiently. In scenarios where documents need to be updated frequently while retaining their historical states, this pattern ensures that changes are tracked and stored without overwriting the original data.