Partitioning is a huge part of Cosmos DB. There are many different strategies you may want to take. Such as, splitting different types of item’s across containers, sharing some IItem
’s in one container and not others and finally, in some cases, even putting all IItem
types in a single container.
Adding the Azure Cosmos Repository with no real configuration, like below. Will result in a simple strategy being assumed on your behalf. This will leave the option’s configured in there default state. This means a property called ContainerPerItemType
is set to false. This means that the Azure Cosmos Repository will store all IItem
’s in the same container, setting all the IItem
’s within to use the partition key /id
.
using Microsoft.Azure.CosmosRepository;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCosmosRepository();
var app = builder.Build();
app.MapGet("/", () =>
"Default Cosmos Repository Partitioning Strategy");
app.Run();
The default partitioning strategy is simple, all IItem
’s will be in a single logical partition split by there unique IDs. Which default to a GUID. This in small applications is often ample. A simple rule of thumb for whether or not this would be okay for you would be, do you see yourself spanning over a physical partition? If no then this option could be the way to go. However, in any scenarios where you are making an application that may grow in size, complexity or scale. It may be best to look at taking a bit more control over your partitioning strategy.
This strategy is also demonstrated in the
WebTier
sample application.
The next configuration allows you to take more control over the partitioning strategy. The first thing to do is to set the ContainerPerItemType
equal to true
. This can be done like in the example below. Once this field has been set, then you need to define which container each IItem
should be placed into and also what partition key it should use. There are currently 2 methods to do this in the Azure Cosmos Repository.
using Microsoft.Azure.CosmosRepository;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCosmosRepository(options =>
{
options.ContainerPerItemType = true;
});
var app = builder.Build();
app.MapGet("/", () =>
"Custom Cosmos Repository Partitioning Strategy");
app.Run();
IItem
Container BuilderThe first option that you have to configure IItem
’s container options is to use the IItemContainerBuilder
which you can access via the RepositoryOptions
. See the examples below.
In the below example we have two IItem
types defined. One is the Customer
item which is configured to be stored in the customers
container, partitioned by /emailAddress
. The second is the Order
item, partitioned by /customerId
.
using Microsoft.Azure.CosmosRepository;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCosmosRepository(options =>
{
options.ContainerPerItemType = true;
options.ContainerBuilder.Configure<Customer>(userContainerOptions =>
{
userContainerOptions.WithContainer("customer");
userContainerOptions.WithPartitionKey("/emailAddress");
});
options.ContainerBuilder.Configure<Order>(orderContainerOptions =>
{
orderContainerOptions.WithContainer("orders");
orderContainerOptions.WithPartitionKey("/customerId");
});
});
var app = builder.Build();
app.MapGet("/", () =>
"Sample e-commerce Partitioning Strategy");
app.Run();
The below example shows how two or more IItem
types can share a container and a partitioning strategy. This defines a Stock
item that might hold the name, price, size, and maybe weight. This is partitioned by the /stockReferenceNumber
. The StockRecord
item is a collection of StockRecord
’s. This record represents when a piece of stock was added or removed from the inventory, when this occurred, and maybe a reason why. This is stored in the same container as the Stock
item whose history it is recording. It also shares the same partitioning strategy. In the example below it means that all Stock
and its StockRecord
’s are stored in the same logical partition in Cosmos DB.
using Microsoft.Azure.CosmosRepository;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCosmosRepository(options =>
{
options.ContainerPerItemType = true;
options.ContainerBuilder.Configure<Stock>(userContainerOptions =>
{
userContainerOptions.WithContainer("stock");
userContainerOptions.WithPartitionKey("/stockReferenceNumber");
});
options.ContainerBuilder.Configure<StockRecord>(orderContainerOptions =>
{
orderContainerOptions.WithContainer("stock");
orderContainerOptions.WithPartitionKey("/stockReferenceNumber");
});
});
var app = builder.Build();
app.MapGet("/", () =>
"Sample Inventory Partitioning Strategy");
app.Run();
Another option to configure a partitioning strategy is to use attributes to decorate your IItem
types. See the examples below.
Customer
Partitioning StrategyThe example below show’s how you can achieve a custom partitioning strategy using attributes.
using Microsoft.Azure.CosmosRepository.Attributes;
using Microsoft.Azure.CosmosRepository;
[Container("customers")]
[PartitionKeyPath("/emailAddress")]
public class Customer : FullItem
{
public string EmailAddress { get; set; }
protected override string GetPartitionKeyValue() =>
EmailAddress;
}
Note the
override
of theGetPartitionKeyValue
method. This is required to tell the library which property to get your partition key value from.