microsoft / spring-data-cosmosdb

Access data with Azure Cosmos DB
MIT License
94 stars 64 forks source link

Support for the Unique Key for a Collection #368

Open jainro opened 5 years ago

jainro commented 5 years ago

Adding Unique Key Constraints in Azure CosmosDB is supported now https://docs.microsoft.com/en-us/azure/cosmos-db/unique-keys

When will this be supported by the spring-data-cosmosdb?

Incarnation-p-lee commented 5 years ago

@mbhaskar Could you please help to share some information about this ?

allenhumphreys commented 5 years ago

The unique key policy should be supported similar to how @DocumentIndexingPolicy works, by supplying an annotation on the document class.

Incarnation-p-lee commented 5 years ago

Thanks a lot, that should be something for serivce side configuration. We will add it to our feature list.

allenhumphreys commented 5 years ago

As a workaround while waiting for first class support of this feature, I have come up with the following (in Kotlin):

Spring Bean Configuration Hooking

```kotlin @Configuration class CosmosUniqueKeyPolicyConfig(val documentDbConfiguration: AbstractDocumentDbConfiguration) { @Bean @Primary fun uniqueKeyPolicyHookingDocumentClient(): DocumentClient = uniqueKeyPolicyHookingDocumentDbFactory().getDocumentClient() @Bean @Primary fun uniqueKeyPolicyHookingDocumentDbFactory(): DocumentDbFactory = UniqueKeyPolicyHookingDocumentDbFactory(documentDbConfiguration.config) @Bean @Primary fun uniqueKeyPolicyHookingDocumentDbTemplate(): DocumentDbTemplate = DocumentDbTemplate( this.uniqueKeyPolicyHookingDocumentDbFactory(), documentDbConfiguration.mappingDocumentDbConverter(), documentDbConfiguration.config.database) } class UniqueKeyPolicyHookingDocumentClient( serviceEndpoint: String?, masterKey: String?, connectionPolicy: ConnectionPolicy?, desiredConsistencyLevel: ConsistencyLevel? ) : DocumentClient(serviceEndpoint, masterKey, connectionPolicy, desiredConsistencyLevel) { override fun createCollection(databaseLink: String?, collection: DocumentCollection?, options: RequestOptions?): ResourceResponse { // Insert a unique key policy to the datamodel collection if (collection?.id == DocumentCollectionNames.datamodel) { collection.uniqueKeyPolicy = DataModel.uniqueKeyPolicy } return super.createCollection(databaseLink, collection, options) } } class UniqueKeyPolicyHookingDocumentDbFactory(config: DocumentDBConfig) : DocumentDbFactory(config) { override fun getDocumentClient(): DocumentClient { val config = config val policy = config.connectionPolicy val userAgent = "MyServer" + ";" + policy.userAgentSuffix policy.userAgentSuffix = userAgent return UniqueKeyPolicyHookingDocumentClient(config.uri, config.key, policy, config.consistencyLevel) } } object DocumentCollectionNames { const val datamodel = "datamodel_collection" } @Document(collection = DocumentCollectionNames.datamodel, ru = "400") data class DataModel( @Id @GeneratedValue val id: String?, @PartitionKey val partitionKey: String, val uniqueKeyWithinPartition: String ) { companion object { val uniqueKeyPolicy: UniqueKeyPolicy by lazy { UniqueKeyPolicy().apply { uniqueKeys = listOf(UniqueKey().apply { paths = listOf("/uniqueKeyWithinPartition") }) } } } } ```

kushagraThapar commented 4 years ago

@allenhumphreys Thanks for the suggestions.

@jainro - I will propose this feature for our next semester.

grzegorz-moto commented 3 years ago

Is there any progress here? I don't see anything in azure-spring-data-cosmos:3.5.0 and the workaround provided here is not adequate anymore