我正在尝试将提供给API的任何JSON存储到BsonDocument中,这是使用C#驱动程序的另一个文档上的字段
但是,当我尝试使用UpdateOne方法时,它只是用我提交的内容替换文档。这是我的顶级mongo文档
public class SomeMongoDocument
{
public ObjectId _id { get; set; }
public string FileName { get; set; }
public BsonDocument Metadata { get; set; }
}
我想最初设置Metadata属性,然后稍后更新,更新可能不包含发送的所有初始元数据。所以当我尝试用这个来更新文档时:
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);
}
它只是覆盖BsonDocument并删除当我将其转换为bson文档时字符串中不存在的属性。
那么我该怎么做呢:
更新现有属性,或者在添加新属性时,保留已存在的属性。感谢
答案 0 :(得分:2)
{ $set: { "metadata": { ... } } }
替换整个metadata
嵌入文档。如果要替换嵌入文档中的值,则应在$set
运算符中指定它们,如:
{$ set:{&#34; metadata.innerField1&#34;:&#34; SomeValue1&#34;,&#34; metadata.innerField2&#34;:&#34; SomeValue2&#34; }
或使用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);
}