Search code examples
azure-cosmosdb

Define unique key constraints that conditionally apply to different documents within the same container/partition


Given the following documents which are stored in the same container and partition where the Type property denotes what the documents type is (DocumentA or DocumentB):

class DocumentA 
{
    public Guid Id { get; set; }
    public Guid ParitionKey { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
}

class DocumentB
{
    public Guid Id { get; set; }
    public Guid ParitionKey { get; set; }
    public int Value { get; set; }
    public string Type { get; set; }
}

Is it possible to create unique key constraints that only apply to either DocumentA or DocumentB?

For example, could I create a unique key constraint on DocumentA's Name property and another for DocumentB's Value property?


Solution

  • Applying unique constraints conditionally based on another property value is not possible, AFAIK.

    I would consider instead:

    Is the unique constraint required at DB-level?

    Is it really so dangerous that you need to verify this on every data-modifying operation? Maybe it is, and it's not a huge burden, but quite often in the schema-less world there are many constraints not enforced on data layer, but in business layer. Contrary to relational-data mindset, it usually works better in NOSQL to keep the storage dumb (except having good targeted indexes for performance) and saving on create/update RU cost may matter more in the big picture.

    Also, changing unique constraints is a PITA, so having one requires you to be really sure that it can accommodate every document type changes and new document types. For example, what if DocumentC pops up with both Name and Value?

    Why force documents with different requirements into the same container?

    If the unique constraints are really-really needed, then you could have the cake and eat it too by just using shared-throughput database and have N containers instead, i.e. differentiated by shared partition key, unique constraints and perhaps main indexes on common structure parts. This has the additional benefits of more granular RBAC access control, more precise indexes, cheaper scans, better names, more readable code, clearer dependencies etc.

    On the downsides of having too many containers:

    • more cumbersome to manage
    • there's a limit (25?) how many containers can be put into same shared-throughput database.
    • loss of ability to query across "types" (for example "docs created between X and Y", etc)