Elfocrash / Cosmonaut

🌐 A supercharged Azure CosmosDB .NET SDK with ORM support
https://cosmonaut.readthedocs.io
MIT License
342 stars 44 forks source link

Synthetic partition key #69

Closed HMoen closed 5 years ago

HMoen commented 5 years ago

First, thank you for putting the work into this great library.

I see that you throw an exception if more than 1 property is decorated with the CosmosPartitionKey attribute. Is there a specific reason?

Instead of having client code populate a single property with a synthetic partition key value (per MS Create a synthetic partition key), could the CosmosPartitionKey be enhanced to allow multi-property decoration with an int position parameter to establish the assembly order? Then use PartitionKeyDefinition when creating the collection to include multiple paths.

Elfocrash commented 5 years ago

Hello @HMoen and thank you for your kind words.

The synthetic key is encouraged from me in general and I do personally use it in prod in multiple use cases. The main problem with having multiple CosmosPartitionKey attributes would be that the library wouldn't know which one is the first part of the synthetic key and which one is the second.

The way I go about it is by creating an object like this:

class Example{
    public string Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    [CosmosPartitionKey]
    public string PartitionKey => $"{FirstName}-{LastName}"
}

This ofc requires the property to be excluded on read it doesn't throw a no-setter exception.

The PartitionKeyDefinition does accept and array but this array is only allowed to have a single partition key path. When they say "synethic partition key" they don't mean, a PartitionKeyDefinition with 2 items in the array. They are talking about a single item which is the concatenated string of two other properties.

HMoen commented 5 years ago

Thanks for the clarification. I had wrongly assumed the PKD would take multiple paths since it is a string collection. In the portal, the placeholder text also shows /address/zipCode as a sample partition key (if I remember correctly) which made me think those were concatenated properties.

Your provided solution will do the trick. Is there a global setting to exclude the property on reads or will need to be set with every query?

Thanks again.

Elfocrash commented 5 years ago

You can specify your JSON conversion settings on both the request level or the CosmosStore level. It comes down to your usecase.

HMoen commented 5 years ago

Perfect, thanks.