MongoDB - 如果 BsonDocument C# 上不存在,则更新字段或添加字段

MongoDB - Update field or Add field if not present on BsonDocument C#

我正在尝试将提供给 API 的任何 JSON 存储到 BsonDocument 中,这是另一个使用 C# 驱动程序的文档上的字段

然而,当我尝试使用 UpdateOne 方法时,它只是用我提交的任何内容替换文档。这是我的顶级 mongo 文档

public class SomeMongoDocument 
{
    public ObjectId _id { get; set; }

    public string FileName { get; set; }

    public BsonDocument Metadata { get; set; }
}

我想初始设置元数据属性,稍后再更新,更新可能不包含所有发送的初始元数据。所以当我尝试用这个更新文档时:

public void UpdateMetadata(string filename, string metadata)
{
        var filter = Builders<SomeMongoDocument>.Filter.Eq(e => e.FileName, filename;

        BsonDocument document = BsonSerializer.Deserialize<BsonDocument>(metadata);

        var update = Builders<SomeMongoDocument>.Update.Set(e => e.Metadata, document);

        this.MongoCollection.UpdateOne(filter, update);

}

当我将它转换为 bson 文档时,它只是覆盖 BsonDocument 并删除字符串中不存在的属性。

那么我该怎么做:

更新现有的 属性,或者在添加新属性时,保留已有的属性。谢谢

{ $set: { "metadata": { ... } } } 替换整个 metadata 嵌入文档。如果您想替换嵌入文档中的值,您应该在 $set 运算符中指定它们,例如:

{ $set: { "metadata.innerField1": "SomeValue1", "metadata.innerField2": "SomeValue2" }

或使用 MongoDB .Net 驱动程序:

Builders<SomeMongoDocument>.Update
    .Set(e => e.Metadata.InnerField1, document.InnerField1)
    .Set(e => e.Metadata.InnerField2, document.InnerField2)
    // ...

由于您的文档中没有预定义的属性,因此您不能以这种方式在代码中对它们进行硬编码。在这种情况下,您可以枚举 BsonDocument 个元素并将它们添加到更新定义中:

UpdateDefinition<SomeMongoDocument> update = null;
foreach (BsonElement element in document)
{
    update = update?.Set(e => e.Metadata[element.Name], element.Value) ??
                Builders<SomeMongoDocument>.Update.Set(e => e.Metadata[element.Name], element.Value);
}

if (update != null)
{
    this.MongoCollection.UpdateOne(filter, update);
}