c# - MongoDb 更新同一数组中的多个特定嵌入式文档

标签 c# mongodb

我有一个用例,其中一个 View 允许用户更新多个对象并一次提交,我怎样才能使它成为原子的?

{_id: parent,
 childrenA: [
   {_id: child1, property: "update-me", property2: "leave-alone"},
   {_id: child2, property: "leave-alone", property2: "update-me"}
 ],
 propertyA: "update-me",
 propertyB: "leave-alone", //someone else needs to be able to update this concurrently with this change.
 childrenB:[
   {property: "update-me", property2: "leave-alone"},
   {property: "leave-alone", property2: "update-me"}
 ],

}

property 可能是也可能不是另一个嵌套对象数组。 这有可能以编程方式实现吗?

编辑:我需要说明的是我无法可靠地更新整个文档 在某些情况下,可以替换嵌入的文档(地址,也许)

但是,我需要汇总一个更改列表,例如[{"child[Id=child1].FirstName", "newName"},{"child[Id=child3].LastName", "newName"}(不一定是那种语法,而是一种改变词典)

最佳答案

据我所知,这可以通过一个限制来完成。如果我错了,请有人纠正我。这是更新命令:

db.Parents.update(
    {
        "_id": ObjectId("5cf7391a1c86292244c4424e"),
        "ChildrenA": {
            "$elemMatch": {
                "_id": ObjectId("5cf7391a1c86292244c4424c")
            }
        }
    },
    {
        "$set": {
            "ChildrenA.$.Property": "UPDATED",
            "PropertyA": "UPDATED",
            "ChildrenB.0.Property": "UPDATED",
            "ChildrenB.1.Property2": "UPDATED"
        }
    }
)

如您所见,您必须使用 $elemMatch 按 ID 定位嵌套子项。据我所知,您只能在单个更新命令中使用一个 $elemMatch(如果我错了请纠正我)。

这是生成上述更新命令的 C# 代码。它正在使用 MongoDB.Entities这是一个便利库,我是它的作者。

using MongoDB.Entities;

namespace StackOverflow
{
    public class Program
    {
        public class Parent : Entity
        {
            public ChildA[] ChildrenA { get; set; }
            public string PropertyA { get; set; }
            public string PropertyB { get; set; }
            public ChildB[] ChildrenB { get; set; }
        }

        public class ChildA : Entity
        {
            public string Property { get; set; }
            public string Property2 { get; set; }
        }

        public class ChildB
        {
            public string Property { get; set; }
            public string Property2 { get; set; }
        }

        static void Main(string[] args)
        {
            new DB("test");

            var childA = new ChildA { Property = "update-me", Property2 = "leave-me-alone" };
            var childB = new ChildA { Property = "leave-alone", Property2 = "update-me" };
            childA.Save(); childB.Save();

            var parent = new Parent
            {
                ChildrenA = new[] { childA, childB },
                PropertyA = "update-me",
                PropertyB = "leave-me-alone",
                ChildrenB = new[] {
                new ChildB{ Property = "update-me", Property2 = "leave-me-alone"},
                new ChildB{ Property = "leave-alone", Property2 = "update-me"}
                }
            };
            parent.Save();

            DB.Update<Parent>()
              .Match(
                f => f.Eq(p => p.ID, parent.ID) &
                f.ElemMatch(
                    x => x.ChildrenA, 
                    x => x.ID == childA.ID))
              .Modify(x => x.ChildrenA[-1].Property, "UPDATED")
              .Modify(x => x.PropertyA, "UPDATED")
              .Modify(x => x.ChildrenB[0].Property, "UPDATED")
              .Modify(x => x.ChildrenB[1].Property2, "UPDATED")
              .Execute();
        }
    }
}

关于c# - MongoDb 更新同一数组中的多个特定嵌入式文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56091781/

相关文章:

node.js - 使用基于角色的应用程序时,如何减少对 MongoDB 实例的调用次数?

php - MongoDB 4.2 中的事务与新的 PHP 驱动程序

database - MongoDB - 语法错误 : illegal character

c# - Gstreamer 在偏移处快速开始音频播放

c# - Visual Studio UML 序列图

c# - "Object can be disposed of more than once"错误

c# - 将 ASP.Net GridView 从一个页面传递到另一个页面

c# - pinvoke 返回一个 float

node.js - 通过 Postman Nodejs 使用承载授权

linux - Centos 7 : Auto restart application if it stopped