4
votes

Description:

I have setup a new Cosmos DB Database with provisioned throughput.This is to share RU/s for all collections and minimizing cost.

My API accessing Cosmos is a Node.JS with Express and Mongoose.

The database is now setup with 1 collection named groups with partition key/shard key partition

I have used Mongoose with Cosmos DB in the past without issues, but when I try in this mode I receive this error message:

{
"_t": "OKMongoResponse",
"ok": 0,
"code": 2,
"errmsg": "Shared throughput collection should have a partition key\r\nActivityId: 9217017f-0000-0000-0000-000000000000, Microsoft.Azure.Documents.Common/2.4.0.0",
"$err": "Shared throughput collection should have a partition key\r\nActivityId: 9217017f-0000-0000-0000-000000000000, Microsoft.Azure.Documents.Common/2.4.0.0",
"name": "MongoError"
}

I have searched a lot for answers, but I do not see anyone else experiencing the same issue running the same environment.

Environment:

  • Node version: v10.16.0
  • Mongoose version: 5.6.6
  • Express version: 4.17.1

Testing:

I have tried setting up the mongoose model like this:

var schema = mongoose.Schema({
    name: String,
}, { shardKey: { partition: "1" }})

And like this:

var schema = mongoose.Schema({
    name: String,
    partition: { type: String, default: "1"},
})

I have also tried to sending the partition key as a value

{
    "name": "Test",
    "partition": "1"
}

If i run the above JSON as a new document in Azure Portal Data Explorer I am able to add the document.

Does anyone know if Mongoose supports Cosmos DB in provisioned throughput-mode? And if it is supported, could I please get an example on how to setup mongoose/the model to get it working.

Thanks

1

1 Answers

1
votes

Your Error

Shared throughput collection should have a partition key

This error is returned when a collection with no specified shard key is created in a database with provisioned throughput. This suggests that mongoose is trying to create the collection rather than using the "groups" one you created. I believe that, to use the groups collection, you should be defining your model:

const Model = mongoose.model("Group", schema)

Another issue I have found is when Mongoose tries to create indexes, it creates the collection system.indexes, which also causes the above error. Things work smoother when autoIndex is off

Hopefully this will fix your issue

Schema Definition

In order to get queries to work, I have found the schema needs to be defined as:

var schema = mongoose.Schema({
    name: String,
    partition: {
        type: Number
        default: 1
    },
}, { shardKey: { partition: "1" }})

If the shardKey option is omitted, you receive the following error:

document does not contain shard key

Mongoose support for creating collections

As far as I can tell, there is no support in mongoose for creating collections in a database with provisioned throughput. It is possible to create collections using the native mongo client, for example:

const db = Model.db.db;

db.command({
    shardCollection: `${dbName}.${collectionName}`,
    key: {
        partition: 'hashed' 
    },
}).then(...)

When I have tried the key { partition: 1 }, I have received the following error:

Only single hashed key is supported for sharded collection.

So I stuck to using 'hashed'

Hope this is of some help