【问题标题】:Update data type of field for all document using MongoDB C# driver使用 MongoDB C# 驱动程序更新所有文档的字段数据类型
【发布时间】:2021-12-29 15:44:28
【问题描述】:

我正在尝试使用 MongoDB C# 驱动程序将集合中所有文档的字段数据类型从字符串更新为 ObjectId。这个查询工作得很好:

db.getCollection('MyCollection').updateMany(
    { MyField: { $type: 2 } },
    [{ $set: { MyField: { $toObjectId: "$MyField" } } }]
);

但我正在努力用 C# 编写相同的查询。 我使用 UpdateManyAsync 尝试了以下查询:

var filter = new BsonDocument("MyField", new BsonDocument("$type", BsonType.String));
                var update = new BsonDocument {
                    { "$set", new BsonDocument("MyField", new BsonDocument("$toObjectId", "$MyField")) }
                };
var updateResult = await collection.UpdateManyAsync(filter, update);

但出现以下错误:

'MyField.$toObjectId' 中的美元 ($) 前缀字段 '$toObjectId' 对存储无效

这个例子在这里有效,但它并不理想,因为它迫使我获取所有文档:

var updateList = new List<WriteModel<BsonDocument>>();
var documents = await collection.Find(Builders<BsonDocument>.Filter.Empty).ToListAsync();

foreach (var document in documents)
{
    var id = document.GetElement("_id").Value.AsString;
    var myFieldValue = document.GetElement("MyField").Value.AsString;

    var filter = Builders<BsonDocument>.Filter.Eq("_id", id);
    var update = Builders<BsonDocument>.Update.Set("MyField", new BsonObjectId(ObjectId.Parse(myFieldValue)));
    updateList.Add(new UpdateOneModel<BsonDocument>(filter, update));
}

if (updateList.Any())
{
    var bulkWriteResult = await collection.BulkWriteAsync(updateList);          
}

【问题讨论】:

  • 从第一个代码和第二个代码中理解。您在第一个中有 $toObjectId,在下一个中有 $toString。也许它会导致错误?
  • 糟糕,这是一个错字。我将编辑问题以解决该问题。
  • 完成,修复了代码示例。很抱歉
  • 找到了一些信息,实际上可能会有所帮助。 mongodb.com/community/forums/t/…
  • 谢谢@kanils_!你给我指明了正确的方向!请在下面检查我的答案。 :)

标签: c# mongodb mongodb-.net-driver


【解决方案1】:

检查一下:

        var pipeline = Builders<BsonDocument>
            .Update
            .Pipeline(new EmptyPipelineDefinition<BsonDocument>()
                .AppendStage<BsonDocument, BsonDocument, BsonDocument>("{ $set: { MyField: { $toObjectId: '$MyField' } } }"));
        coll.UpdateMany(
            new BsonDocument("MyField", new BsonDocument("$type", BsonType.String)),
            pipeline);

【讨论】:

    【解决方案2】:

    此代码示例有效:

    var filter = new BsonDocument("MyField", new BsonDocument("$type", BsonType.String));
    var stage = new BsonDocument { { "$set", new BsonDocument { { "MyField", new BsonDocument { { "$toObjectId", "$MyField" } } } } } };
    var pipeline = PipelineDefinition<BsonDocument, BsonDocument>.Create(stage);
    var update = Builders<BsonDocument>.Update.Pipeline(pipeline);
    
    var result = await collection.UpdateManyAsync(filter, update);
    

    非常感谢@kanils_ 你为我指明了正确的方向,这个例子Mongo Db driver C# aggregation for update 也帮助我编写了上面的代码。也非常感谢@dododo 的建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-02
      • 1970-01-01
      相关资源
      最近更新 更多