Search code examples
azureazure-cosmosdbazure-cosmosdb-mongoapi

How to create a collection in a shared throughput cosmosdb using the Mongo API


I have an Azure CosmosDb database with database-level throughput provisioned. We're using the MongoDB API against this Cosmos instance. The shared throughput model requires all collections to have a partition key specified, which seems to prevent pretty much any tools from being able to create a collection, other than the Azure Portal or the official Azure Cosmos SDKs. For example, in Robo 3T, attempting to create a collection results in the following error:

Failed to create collection 'mycollection'.

Error: Shared throughput collection should have a partition key

The same error occurs when attempting to create a collection via mongoose (similar to this question) or other tooling.

So I guess the operative question boils down to this: Is there any way through the MongoDb API to pass the desired partitionKey to CosmosDb, so that collection creation will succeed?


Solution

  • Use the shardCollection command via db.runCommand(...)

    It turns out there is a working, if obscure, way to achieve this with the MongoDb wire protocol. You can create a collection with a Cosmos partition key (which conceptually maps to the Mongo Shard Key), by issuing a db-level command to set the sharding key for the not-yet-existing collection:

    In a mongo shell:

    db.runCommand({shardCollection: "myDbName.nameOfCollectionToCreate", 
                   key: {nameOfDesiredPartitionKey: "hashed"}})
    

    After running this, my ComosDb database (with database-level shared throughput) now contains the new collection with the partition key set appropriately!

    I haven't figured out a way to call runCommand directly via Mongoose yet, but at least this native/wire protocol approach should work with any of the official MongoDb drivers, so is far more portable than depending on the Azure Cosmos SDK just to create a collection.