使用官方C#驱动程序更新MongoDB中嵌套文档(2级深度)

3

我在更新一个文档中嵌套的文档时遇到了问题,这个文档有两个级别的深度。

我已经阅读了这篇文章 使用官方C#驱动程序更新MongoDB中的嵌入式文档,但那个问题只有一层深度,因此语法可能不同。

使用官方10 gen C#驱动程序版本1.0更新以下嵌入式文档的正确语法是什么?

{
  "_id": {
    "$oid": "4dfa2601dc1c791d40106a25"
  },
  "_t": "Model",
  "TypeId": 1,
  "Title": "Some Title",
  "ObjectBags": [
    {
      "_t": "ObjectBag",
      "_id": {
        "$oid": "4dfa2603dc1c791d40107e48"
      },
      "TypeId": 4,
      "Objects": [
        {
          "_t": "DomainObject",
          "_id": {
            "$oid": "4dfa2603dc1c791d40107e49"
          },
          "TypeId": 4,
          "ParentId": {
            "$oid": "4dfa2603dc1c791d40107e48"
          },
          "CreatedBy": "me",
          "CreatedDate": "Thu, 16 Jun 2011 08:49:21 GMT -07:00",
          "LastUpdatedBy": "me",
          "LastUpdatedDate": "Thu, 16 Jun 2011 08:49:21 GMT -07:00",
          "InactivatedDate": null,
          "Data": "1`|`11536"
        }
      ]
    }
  ]
}

这是我尝试过的,没有错误提示,但是什么也没有更新。

var models = _database.GetCollection<Model>("Models");
var model = models.FindOneAs<Model>(Query.EQ("_id", new ObjectId("4dfa2601dc1c791d40106a25")));

var wspwRef = model.Objects.Find(Domain.Object.Reference);
wspwRef.Set(Domain.Field.Reference.Name, "SOME REF RM");

var query = Query.EQ("ObjectBags.Objects._id", new ObjectId("4dfa2603dc1c791d40107e49"));
var documentWrapper = BsonDocumentWrapper.Create<DomainObject>(wspwRef);
models.Update(query, Update.Set("ObjectBags.Objects.$", documentWrapper));

文档包装器从新更新的对象中生成以下内容。
{ 
  "_id" : { "$oid" : "4dfa2603dc1c791d40107e49" }, 
  "TypeId" : 4, 
  "ParentId" : { "$oid" : "4dfa2603dc1c791d40107e48" }, 
  "CreatedBy" : "me", 
  "CreatedDate" : { "$date" : 1308239361784 }, 
  "LastUpdatedBy" : "me", 
  "LastUpdatedDate" : { "$date" : 1308239791540 }, 
  "InactivatedDate" : null, 
  "Data" : "1`|`11536^|^2`|`SOME NEW TEXT" 
}

不确定名称"ObjectBags.Objects.$"是否是问题或其他原因。


我认为Robert的评论非常准确。您正在尝试更新属于数组中对象的数组中的对象。当前的更新语法对此并不支持。您可以硬编码数组位置(ObjectBags.0.Objects.0.Data),或者检索并保存整个对象。 - Gates VP
1个回答

1

我不确定这是否可能。问题的一部分在于你有两个数组(ObjectBags和Objects),而我只见过$符号与一个数组一起使用。

无论如何,对于像这样的困难更新问题,最好的方法是在Mongo shell中进行实验和故障排除,一旦在那里解决了问题,就可以将语句转换为C#。

您始终可以在客户端传输整个文档,并使用C#在本地执行更新,然后将文档保存回数据库。这不是原子性的,如果您的文档非常大,则涉及更多的网络流量,但有时它可能更简单。


你提出的替代方案是在客户端更改整个文档,那么您是否建议拉回原始的BsonDocument(模型),并对其进行更改? - srdemart
我问的原因是因为我试图保存反序列化的模型,但似乎没有遍历层次结构以保存嵌套的更改。如果每个级别都有更改,它会吗? - srdemart
是的,如果要在客户端进行更改,则首先必须将整个文档(作为BsonDocument或反序列化为域模型类的实例)拉到客户端。当您调用Save(无论是在BsonDocument上还是在域模型类的实例上)时,整个文档都会被保存,无论更改了什么或未更改。 - Robert Stam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接