如何使用mongodb更新包含在父对象的数组中的对象的属性?
如何使用mongodb更新包含在父对象的数组中的对象的属性?
我使用MongoDB作为我的数据库。我有一个数据:
{ _id : '123' friends: [ {name: 'allen', emails: [{email: '11111', using: 'true'}]} ] }
现在,我想修改用户的朋友们的邮件地址,其_id为'123'。我写了如下代码:
db.users.update({_id: '123'}, {$set: {"friends.0.emails.$.email" : '2222'}})
这看起来很简单,但是当emails数组有两个或更多的数据时,代码就会出错。所以,我的问题是:
如何修改嵌套字段中的数据 - 只有两个或更多的嵌套数组?谢谢。
问题的原因是:需要更新包含在父对象的数组中的对象的属性,但是不知道如何使用MongoDB来实现这一操作。
解决方法是使用arrayFilters来查询并分配索引给一个标识符,以实现对多层级数组的更新。具体操作如下:
db.collection.update( {}, { : { "array.$[ ].field" : value } }, { arrayFilters: [ { : } ] } )
下面是提供的示例和一个具有两个电子邮件的新朋友:
{ _id : '123', friends: [ {name: 'allen', emails: [ {email: '11111', using: 'true'} ]}, {name: 'lucy' , emails: [ {email: 'lucy.com', using:'true'}, {email:'lucyGucy.com', using : 'false'} ]} ] }
假设需要将"lucyGucy.com"更新为"lucy.is.gucy.com"。可以使用数组过滤器中的"name"和"email"字段来识别要更新的索引。具体操作如下:
db.users.update({_id:123}, {$set:{ "friends.$[updateFriend].emails.$[updateEmail].email" : "lucy.is.gucy.com" }}, { "arrayFilters": [ {"updateFriend.name" : "lucy"}, {"updateEmail.email" : "lucyGucy.com"} ] })
通过这种方式,更新不受特定数组顺序的影响。上述示例使用了两个标识符"updateFriend"和"updateEmail",它们将匹配满足数组过滤器条件的数组元素。需要注意的是,标识符必须以小写字母开头,并且只能包含字母数字字符。
此外,虽然电子邮件可能是唯一的,但建议在所有子文档上包含一个唯一的ID,以便数组过滤器可以精确匹配。
问题的原因是需要更新包含在父对象的数组中的对象的属性。解决方法是使用Mongoose库中的findById方法来查找父对象,然后通过遍历父对象的数组找到目标对象,并更新其属性。最后,使用save方法保存更新后的父对象。
以下是使用Mongoose解决问题的代码示例:
Users.findById("123", function(err, user) { var friends = user.friends; for (i = 0; i < friends.length; i++) { if (friends[i].name == 'allen') { friends[i].email = '2222'; user.save(function(err) { if (err) throw err; console.log("email updated"); }); } else { console.log("no friends named allen"); } } }
问题的原因:用户想要更新父对象中包含的数组中的对象的属性,但不知道该对象在数组中的索引位置。
解决方法:使用 MongoDB 的点符号(Dot Notation)来更新数组中的元素。将$替换为要更新的元素在数组中的基于零的索引位置。通过查询_id为'123'的记录,并使用findOne()方法检索记录,然后使用JavaScript进行任何操作,并使用save()方法将其保存回数据库。
代码示例:
db.users.update({_id: '123'}, {'$set': {"friends.0.emails.0.email": '2222'}});
以上代码将更新第一个朋友的第一个电子邮件。
db.users.update({_id: '123'}, {'$set': {"friends.0.emails.1.email": '2222'}});
以上代码将更新第一个朋友的第二个电子邮件。
然而,如果不知道电子邮件在数组中的位置,不能直接在更新语句中解决这个问题。可以通过查询_id为'123'的记录,并使用findOne()方法检索记录。然后使用JavaScript进行任何操作,找到要更新的电子邮件,并将其修改为所需的值,最后使用save()方法将记录保存回数据库。
注意:如果多个线程或服务器同时进行操作,使用pull和save方法会导致原子性丢失,可能会导致数据被覆盖。