更新嵌套数组中的属性值

时间:2015-09-23 05:31:47

标签: mongodb meteor

我的名为user的集合有6个字段。配置文件字段是文档。它只有名为Packages的数组。包是文档集合,包含当前用户拥有的所有包。

我的数据库就像:

{
  "_id" : "AayujR3SLT5MtmTKf",
  "createdAt" : ISODate("2015-09-18T07:19:05.069Z"),
  "services" : {
    "password" : {
      "bcrypt" : "encripted_password_here"
    }
  },
  "username" : "test_user",
  "emails" : [{
      "address" : "1@gmail.com",
      "verified" : false
    }],
  "profile" : {
    "packages" : [{
        "packageId" : "67fmCMNTdqejFs7NE",
        "name" : "package1"
        "active" : true
      }, {
        "packageId" : "Dcn4PkmHNe8APuk73",
        "name" : "package2"
        "active" : true
      }, {
        "packageId" : "yvdXkPeNHEWwwLKjC",
        "name" : "package2"
        "active" : true
      }]
  }
}

我想将所有活动设置为false。我该怎么办?我目前的代码就像(不工作):

Meteor.users.update({ _id: Session.get('user_id') }, { $set: {'profile.packages.active': false} });

1 个答案:

答案 0 :(得分:1)

由于“packages”数组中有许多元素,因此无法在单个查询中完成。即使您尝试以下查询,也只会在当前文档中更新第一个匹配项,其余部分将保持不变。

db.exp10.update({"profile.packages.active":true},{$set:{"profile.packages.$.active":false}},{multi:true})

输出:

{
        "_id" : "AayujR3SLT5MtmTKf",
        "createdAt" : ISODate("2015-09-18T07:19:05.069Z"),
        "services" : {
                "password" : {
                        "bcrypt" : "encripted_password_here"
                }
        },
        "username" : "test_user",
        "emails" : [
                {
                        "address" : "1@gmail.com",
                        "verified" : false
                }
        ],
        "profile" : {
                "packages" : [
                        {
                                "packageId" : "67fmCMNTdqejFs7NE",
                                "name" : "package1",
                                "active" : false
                        },
                        {
                                "packageId" : "Dcn4PkmHNe8APuk73",
                                "name" : "package2",
                                "active" : true
                        },
                        {
                                "packageId" : "yvdXkPeNHEWwwLKjC",
                                "name" : "package2",
                                "active" : true
                        }
                ]
        }
}

我们可以使用下面的代码做得更好:

db.user.find({"profile.packages.active":true}).forEach(function(doc){
for( var count = 0; count < doc.profile.packages.length; count++ )
{
    if( doc.profile.packages[count].active == true )
        doc.profile.packages[count].active = false;     
}
db.user.save(doc);
});

输出:

{
        "_id" : "AayujR3SLT5MtmTKf",
        "createdAt" : ISODate("2015-09-18T07:19:05.069Z"),
        "services" : {
                "password" : {
                        "bcrypt" : "encripted_password_here"
                }
        },
        "username" : "test_user",
        "emails" : [
                {
                        "address" : "1@gmail.com",
                        "verified" : false
                }
        ],
        "profile" : {
                "packages" : [
                        {
                                "packageId" : "67fmCMNTdqejFs7NE",
                                "name" : "package1",
                                "active" : false
                        },
                        {
                                "packageId" : "Dcn4PkmHNe8APuk73",
                                "name" : "package2",
                                "active" : false
                        },
                        {
                                "packageId" : "yvdXkPeNHEWwwLKjC",
                                "name" : "package2",
                                "active" : false
                        }
                ]
        }
}

P.S:

如果该集合包含许多文档,为了获得更好的效果,我们可以使用Bulk Operations