UpdateOneModel,带有 Upsert - 错误 _id Mongodb C# MongoDB.Driver

UpdateOneModel, with Upsert - error _id Mongodb C# MongoDB.Driver

我正在尝试使用 c# 执行批量写入 https://mongodb.github.io/mongo-csharp-driver/2.7/reference/driver/crud/writing/#bulk-writes - 我可以得到 70-80K 的文档列表。

var correlationIdFilter = Builders<BsonDocument>.Filter.AnyIn("CorrelationId", ninKeysRecon);
var missingData = collection.Find(correlationIdFilter).ToList();

缺失数据数据样本

{ 
    "_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}

然后我创建选项和 bulkOps

var options = new UpdateOptions { IsUpsert = true };
var bulkOps = new List<WriteModel<BsonDocument>>();

我不知道我是否需要遍历 missingData 来创建一个新的 UpdateOneModel() 但我正在努力查看在哪里或如何创建过滤器,因为当我将 _id 设置为过滤器时,我得到错误 _id 字段是不可变的。我不想覆盖 _id 但我只是想实现这样的事情

collection.UpdateMany(correlationIdFilter, missingBson, options);

或者如果我必须创建一个 for 循环,我已经尝试过:

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);

我收到错误:

WriteErrors:[{ 类别:“未分类”,代码:66,消息:“对路径‘_id’执行更新将修改不可变字段‘_id’”}]。'

删除 - { IsUpsert = true } 运行正常,但没有执行我需要的任何升级。

谢谢

传递给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 是不可变的,这意味着它无法更改。这是一个问题,因为您传递给 $set 的数据包含一个 _id 字段,该字段不是 1.

相反,在过滤器文档中,您应该传递要插入的文档的 _id

foreach(var data in missingBson)
{
    var upsert = new UpdateOneModel<BsonDocument>(
    new BsonDocument("_id", data._id),
    new BsonDocument("$set", data)) { IsUpsert = true };
    bulkOps.Add(upsert);
}

这样 _id 字段匹配,并且您不会尝试为每个写入操作更新具有 1_id 的文档。