We have been using the MongoDB API with CosmosDB (Server v3.6) quite extensively the last few months via .NET Core and latest MongoDB.Driver Nuget package (2.11.0).
Bulk Inserts and inserts work fine, but unfortunately, I cannot get bulk operations to work with the IsUpsert=true
mode.
Note:
- We use
Polly
to manage rate limiting. As part of this, we handleMongoWriteException, MongoExecutionTimeoutException, MongoCommandException
andMongoBulkWriteExceptions
.- This issue can be observed for both sharded/non-sharded collections.
Specifically, given a list of non-sharded input documents List<T> documents
, the following works fine:
Bulk Insert:
await Collection.BulkWriteAsync(documents.Select(s => new InsertOneModel<T>(s)),...)
Bulk Update:
await Collection.BulkWriteAsync(documents.Select(s => new ReplaceOneModel<T>(Builders<T>.Filter.Eq("Id", item.Id), item) { IsUpsert = false }),...)
Unfortunately, if some of the documents are new documents, we should be able to use the bulk update code above as is - but simply set the IsUpsert flag to true... but alas, this isn't working.
Specifically, given 50 existing documents and 50 new documents:
- If document has Id of type
ObjectId
as primary key, for the first new document it processes, CosmosDb will incorrectly insert it withId=ObjectId("000000000000000000000000")
- and at that point no further documents will be inserted/updated. In this scenario:BulkWriteResult
returned withMatchedCount=65, ModifiedCount=65, ProcessedRequests=100, RequestCount=100, Upserts=1, IsAcknowledged=true, IsModifiedCountAvailable=true, InsertedCount=0
- No exception thrown.
- Note - only 51 documents are in the database, so one can't rely on
BulkWriteResult
- If document has Id of type
int
as primary key then cosmos db seems to- give up processing documents at some random point. This appears more of a rate-limiting type of scenario...EXCEPT that no exception is thrown.
- For example, update all 50 documents but only inserted 8. In this case,
BulkWriteResult
returns withMatchedCount=50, ModifiedCount=50, ProcessedRequests=100, RequestCount=100, Upserts=8, IsAcknowledged=true, IsModifiedCountAvailable=true, InsertedCount=0
.
What am I missing? The ObjectId
scenario seems totally broken; the other scenario could be coded around but it doesn't seem correct that no exception raised here.