Jeff Widmer
Jeff Widmer

Reputation: 4876

Require unique username when Users container has userId as partition key

I am using this article as an example https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-model-partition-example with a Users container with userId and username and the partition key as userId.

{
    "id": "54c7da13-f4b8-4668-90dc-7c1aa968a73e",
    "userId": "54c7da13-f4b8-4668-90dc-7c1aa968a73e",
    "type": "user",
    "username": "jeffw"
}

In my create user page I want to make sure the username is unique before adding a new user. I tried a pre-trigger but found that "You can't run stored procedures or triggers across multiple logical partitions." How do I make sure that when a user is created that they have selected a unique username? I think I could change the partition key to username but why does the article use userId instead?


SOLUTION

See answer from @mark-brown.

Create a unique key on the Users container and /username:

await database.Database.DefineContainer(name: "Users", partitionKeyPath: "/userId")
                            .WithUniqueKey().Path("/username").Attach()
                            .CreateIfNotExistsAsync();

Then try to create a new User with userId as "unique_username" and the new username that is attempting to be created:

{
    "id": "06af2937-4677-4d27-a167-5517aa6d0ffd",
    "userId": "unique_username",
    "type": "unique_username",
    "username": "jeffw"
}

await _usersContainer.CreateItemAsync(uniqueUser, new PartitionKey("unique_username"));

This will return a Conflict status if the username already exists. Example is here https://github.com/jwidmer/AzureCosmosDbBlogExample/blob/master/BlogWebApp/Services/BlogCosmosDbService.cs

Upvotes: 1

Views: 348

Answers (2)

Tim P.
Tim P.

Reputation: 2942

You can set up an index policy for unique values.

Upvotes: 0

Mark Brown
Mark Brown

Reputation: 8763

Changing the partition key to username won't help because you can have multiples of that value in your container. One way you could do this is to have a new partition where you store a unique instance for every user name and use a unique index on the container (unique indexes are unique within a logical partition).

Create a new type = "unique_user" and a userId = "unique_user". Then add a new record of that type with the new username as they register. This should get you millions of users without going over the 20GB limit. Then when creating a new user do an insert on the container with the "unique_user" type and id with the new username. If you get a 201 then do another insert with type= "user" and the rest of the user data.

hope that helps.

Upvotes: 2

Related Questions