I am trying to perform a bulkwrite with c# https://mongodb.github.io/mongo-csharp-driver/2.7/reference/driver/crud/writing/#bulk-writes - I could have a list of documents from 70-80K.
var correlationIdFilter = Builders<BsonDocument>.Filter.AnyIn("CorrelationId", ninKeysRecon);
var missingData = collection.Find(correlationIdFilter).ToList();
Missing Data Data Sample
{
"_id" : ObjectId("61dd323bfe35f25bb2dcde8e"),
"CorrelationId" : "17bd621d-e47f-4ab1-9004-9543294a4549",
"Key" : "123",
"Date" : "2016-06-28T00:00:00",
"CurrentDate" : ISODate("2022-01-11T07:31:07.011 0000"),
"SourceSystem" : "abc",
"SourceEntity" : "source"
},
{
"_id" : ObjectId("61dd323bfe35f25bb2dcd123"),
"CorrelationId" : "18bd621d-e47f-4ab1-9004-9543294a4549",
"Key" : "123232324",
"Date" : "2016-06-28T00:00:00",
"CurrentDate" : ISODate("2022-01-11T07:31:07.011 0000"),
"SourceSystem" : "abc",
"SourceEntity" : "source"
},
.
.
.
{100K Documents}
Then I createoptions and bulkOps
var options = new UpdateOptions { IsUpsert = true };
var bulkOps = new List<WriteModel<BsonDocument>>();
I dont know if I need to loop through missingData to create a new UpdateOneModel() but I am struggling to see where or how to create a filter because when I set _id as a filter, I get the error _id field is immutable. I do not want to overwrite the _id but I simply want to achieve something like this
collection.UpdateMany(correlationIdFilter, missingBson, options);
Or if I have to create a for loop, I have tried:
foreach(var data in missingBson)
{
var upsert = new UpdateOneModel<BsonDocument>(
new BsonDocument("_id", 1),
new BsonDocument("$set", data)) { IsUpsert = true };
bulkOps.Add(upsert);
}
collection.BulkWrite(bulkOps);
I get the error:
WriteErrors: [ { Category : "Uncategorized", Code : 66, Message : "Performing an update on the path '_id' would modify the immutable field '_id'" } ].'
removing - { IsUpsert = true } runs fine but doesn't do any upserting which I need.
Thank you
CodePudding user response:
The first argument passed to UpdateOneModel
is the filter. The filter tells MongoDB which document you want to update. You pass new BsonDocument("_id", 1)
, which tells MongoDB you want to update the document with an _id
of 1
. _id
is a special field in MongoDB documents:
The field name _id is reserved for use as a primary key; its value must be unique in the collection, is immutable, and may be of any type other than an array. If the _id contains subfields, the subfield names cannot begin with a ($) symbol
_id
is immutable, meaning it cannot be changed. This is an issue because the data you are passing to $set
contains an _id
field that is not 1
.
Instead, in the filter document you should be passing the _id
of the document you are trying to insert.
foreach(var data in missingBson)
{
var upsert = new UpdateOneModel<BsonDocument>(
new BsonDocument("_id", data._id),
new BsonDocument("$set", data)) { IsUpsert = true };
bulkOps.Add(upsert);
}
This way the _id
fields match, and you are not attempting to update a document with an _id
of 1
for each write operation.