如何使用C#驱动程序更新MongoDB中数组子文档中包含的数组子文档中的字段?

时间:2014-11-06 15:58:19

标签: c# mongodb

我在MongoDB中有一个文档集合,其结构如下(有多个容器文档,每个包含Sessions,每个会话包含1个订单,每个订单包含多个项目):

{
  "Sessions" : [{
      "ID" : "1882a092-d395-45d1-b36b-e2fa3df81b95",
      "Order" : {
        "Items" : [{
            "_id" : "a9c94a5e-10ef-433d-9c63-f4555eb7c2a7",
            "Title" : "UPDATE THIS",
          }]
      }
    }],
  "_id" : "1b640bc4-fdb4-49b1-9c60-e4c6f1bd0405"
}

我想知道会话中订单中给定Title的{​​{1}},同时知道项目的Item(如果有帮助,我也知道会话的ID) :

我尝试了以下内容:

_id

两者都抛出异常col.Update(Query.EQ("Sessions.ID", sessionID), Update.Set("Sessions.$.Order.Items.Title", newTitle)); col.Update(Query.EQ("Sessions.Order.Items._id", id), Update.Set("Sessions.Order.Items.$.Title", newTitle)); 。我还尝试使用WriteConcern detected an error 'cannot use the part (Sessions of Sessions.Order.Items.0.Status) to traverse the element ...组合查询的不同组合,这些组合可能没有多大意义,因为它们不值得在这里发布。

如何使用C#驱动程序更新文档数组中包含的子文档中的字段?

我意识到这不能单独使用位置运算符(并且位置运算符不会神奇地匹配内部数组)。

我正在寻找开箱即用的解决方案,如何在不更改架构的情况下完成此类更新。

2 个答案:

答案 0 :(得分:5)

您没有更新子文档的子文档。 您正在更新父数组子文档中的数组子文档的一个字段。

您可以通过代码打击

更新第一个元素
col.Update(Query.EQ("Sessions.ID", sessionID),
                Update.Set("Sessions.$.Order.Items.0.Title", newTitle));

使用简单的更新查询,您无法更新所有元素的标题。 此链接可能对您有帮助(使用自定义JavaScript更新查询)

How to multi update of a nested array in MondoDB?

答案 1 :(得分:3)

来自@Disposer的回答帮助我找到了解决方案。它在我的代码库中传播了多个区域,但我想与可能遇到类似问题的其他人分享基本要点。

以下是步骤:

  • 锁定给定订单,不允许将项目添加到其中(在应用程序级别)。
  • 或者,使用其他WriteCount字段的组合,并使用findAndModify仅在文档尚未更新的情况下以原子方式更新文档("更新当前和#34) ;)

然后,在更新给定项目的Title时:

  • 使用已存储的WriteCount
  • 确定项目索引
  • 将项目索引与位置运算符$结合使用以识别会话,使用整数index来定位项目,同时使用"更新当前"策略使用WriteCount字段。

然后更新部分变为:

"Sessions.$.Order.Items." + index + ".Title"