使用 c# 更新 Mongo 中的嵌套数组
Update a nested Array in Mongo with c#
我有这样的文档
{
"_id": "63dafa72f21d48312d8ca405",
"tasks": [{
"_ref": "63d8d8d01beb0b606314e322",
"data": {
"values": [{
"key": "Deadline",
"value": "2014-10-13"
}]
}
}, {
"_ref": "84dd046c6695e32322d842f5",
"data": {
"values": []
}
}]
}
现在,如果 _ref 字段与我的输入匹配,我想更新 values 中的值,也就是 data 中的值。
到目前为止我的代码:
public bool updateProject(Project dbPro, Project pro)
{
var collection = db.GetCollection<BsonDocument>("projects");
var filter = Builders<BsonDocument>.Filter.Eq("_id", ObjectId.Parse( dbPro.Id));
var update = Builders<BsonDocument>.Update.AddToSetEach("tasks", pro.Tasks);
var result = collection.UpdateOne(filter, update);
if (result.IsModifiedCountAvailable)
{
if (result.ModifiedCount == 1)
{
return true;
}
}
return false;
}
目前此代码仅将文档附加为新任务,而不是将值附加到匹配任务。也许有人知道如何实现这种行为?
更新
我像@Shane Oborn 说的那样试过了。但它仍然不适合我。
var collection = db.GetCollection<BsonDocument>("projects");
var filter = Builders<BsonDocument>.Filter.Eq("_id", ObjectId.Parse( dbPro.Id));
var update = Builders<BsonDocument>.Update.Push("tags", buildBsonArrayFromTags(pro.Tags));
var result = collection.UpdateOne(filter, update);
if (result.IsModifiedCountAvailable)
{
if (result.ModifiedCount == 1)
{
return true;
}
}
return false;
}
为了覆盖数据,它向我的数组附加了一个数组。
更新
好的,我确实需要设置而不是推送。然后就成功了。
我没有可访问的确切代码,但关闭了。我有一个执行 "upserts" 的方法(如果是新的 "adds",如果存在则 "updates")。这应该让你接近:
// The variable "doc" below is a BsonDocument
var updateRequests = new List<WriteModel<BsonDocument>>();
updateRequests.Add(new ReplaceOneModel<BsonDocument>(
CreateBsonDocumentFilterDefinition(filterKeyName, filterKeyValue), doc)
{
IsUpsert = true
});
var writeResult = await collection.BulkWriteAsync(updateRequests);
此处为您提供的关键对象是 "ReplaceOneModel" 和过滤器定义的 "IsUpsert" 属性。
祝你好运!
更新:
我拥有的另一种更新子文档的方法如下所示:
// Below, "subDocument" is a BsonDocument, and "subDocArrayName" is a string
// that should match the name of the array that contains your sub-document
// that will be updated.
var collection = _database.GetCollection<BsonDocument>(collectionName);
var builder = Builders<BsonDocument>.Update;
var update = builder.Push(subDocArrayName, subDocument);
await collection.UpdateOneAsync(CreateBsonDocumentFilterDefinition(filterKeyName, filterKeyValue), update);
我有这样的文档
{
"_id": "63dafa72f21d48312d8ca405",
"tasks": [{
"_ref": "63d8d8d01beb0b606314e322",
"data": {
"values": [{
"key": "Deadline",
"value": "2014-10-13"
}]
}
}, {
"_ref": "84dd046c6695e32322d842f5",
"data": {
"values": []
}
}]
}
现在,如果 _ref 字段与我的输入匹配,我想更新 values 中的值,也就是 data 中的值。
到目前为止我的代码:
public bool updateProject(Project dbPro, Project pro)
{
var collection = db.GetCollection<BsonDocument>("projects");
var filter = Builders<BsonDocument>.Filter.Eq("_id", ObjectId.Parse( dbPro.Id));
var update = Builders<BsonDocument>.Update.AddToSetEach("tasks", pro.Tasks);
var result = collection.UpdateOne(filter, update);
if (result.IsModifiedCountAvailable)
{
if (result.ModifiedCount == 1)
{
return true;
}
}
return false;
}
目前此代码仅将文档附加为新任务,而不是将值附加到匹配任务。也许有人知道如何实现这种行为?
更新
我像@Shane Oborn 说的那样试过了。但它仍然不适合我。
var collection = db.GetCollection<BsonDocument>("projects");
var filter = Builders<BsonDocument>.Filter.Eq("_id", ObjectId.Parse( dbPro.Id));
var update = Builders<BsonDocument>.Update.Push("tags", buildBsonArrayFromTags(pro.Tags));
var result = collection.UpdateOne(filter, update);
if (result.IsModifiedCountAvailable)
{
if (result.ModifiedCount == 1)
{
return true;
}
}
return false;
}
为了覆盖数据,它向我的数组附加了一个数组。
更新
好的,我确实需要设置而不是推送。然后就成功了。
我没有可访问的确切代码,但关闭了。我有一个执行 "upserts" 的方法(如果是新的 "adds",如果存在则 "updates")。这应该让你接近:
// The variable "doc" below is a BsonDocument
var updateRequests = new List<WriteModel<BsonDocument>>();
updateRequests.Add(new ReplaceOneModel<BsonDocument>(
CreateBsonDocumentFilterDefinition(filterKeyName, filterKeyValue), doc)
{
IsUpsert = true
});
var writeResult = await collection.BulkWriteAsync(updateRequests);
此处为您提供的关键对象是 "ReplaceOneModel" 和过滤器定义的 "IsUpsert" 属性。
祝你好运!
更新:
我拥有的另一种更新子文档的方法如下所示:
// Below, "subDocument" is a BsonDocument, and "subDocArrayName" is a string
// that should match the name of the array that contains your sub-document
// that will be updated.
var collection = _database.GetCollection<BsonDocument>(collectionName);
var builder = Builders<BsonDocument>.Update;
var update = builder.Push(subDocArrayName, subDocument);
await collection.UpdateOneAsync(CreateBsonDocumentFilterDefinition(filterKeyName, filterKeyValue), update);