我有一个具有以下形式的对象:
{
"_id": ObjectId("4fa43f4d1cf26a6a8952adf1"),
"userId": "1",
"facebookId": "1234",
"groups": [{
"groupName": "testGroup",
"members": [{
"memberFirstName": "userFirstName",
"memberLastName": "userLastName",
"memberDetails": {
"userId": "1",
"faceBookId": "1234"
}
}]
}]
}
这是一个包含每个用户的集合 - 它的组, 每个小组都包含小组成员...... 因此“groups”键是一个数组(或列表),“members”键也是如此。 (每个用户可以有多个组,每个组有多个组成员)。
我很难用新的组成员更新对象, 我要做的是:
db.collection.update({
userId: "1"
}, {
$push: {
"groups.members": {
membersDetails: {
userId: "2",
faceBookId: "54321"
},
memberFirstName: "UserB",
memberLastName: "UserBLastName"
}
}
});
但它似乎不起作用。
收到以下错误:
can't append to array using string field name [members]
我也在尝试使用Java驱动程序,但这似乎不起作用。
DBObject query = new BasicDBObject("userId", "1");
DBObject newMemberDetailsObj = new BasicDBObject();
newMemberDetailsObj.put("userId", "2");
newMemberDetailsObj.put("faceBookId", "54321");
DBObject newMemberObj = new BasicDBObject();
newMemberObj.put("memberFirstName", "userB");
newMemberObj.put("memberLastName", "UserBLastName");
newMemberObj.put("memberDetails", newMemberDetailsObj );
DBObject update = new BasicDBObject("$push", new BasicDBObject("members", newMemberObj));
update.put("groupName", "testGroup");
DBObject maintain = new BasicDBObject("$push", new BasicDBObject("groups", update));
WriteResult newWr = coll.update(query, maintain);
答案 0 :(得分:4)
这不起作用,因为groups
是一个数组,但你引用它中的属性就像它是一个对象一样。您可以访问groups.0.members
或groups.1.members
之类的内容,因为它们引用了数组中的特定项,但groups
对象本身没有要追加的members
属性。
我不完全确定您的更新需要做什么,但您可以在groups.groupName
上为您的查询添加过滤器,然后使用$push
groups.$.members
附加一个过滤器成员只对匹配的组。
http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator
答案 1 :(得分:4)
这是因为您的用户模型可以有多个组,因此您需要匹配过滤器中的组并在更新中使用位置运算符$
。所以你的更新将是这样的(未经测试):
db.collection.update({
userId: "1",
"groups.groupName": "testGroup" // match against the group here
}, {
$push: {
"groups.$.members": { // notice the use of the $ here
membersDetails: {
userId: "2",
faceBookId: "54321"
},
memberFirstName: "UserB",
memberLastName: "UserBLastName"
}
}
});
当你有一个值数组时,位置运算符基本上是“在数组中匹配值的位置”。
然而,你只能深入了解这个级别的数组,所以你无法匹配特定组中的特定成员,例如 - 所以你可能想要分手如果您需要做这类事情,请将您的文档分成许多更简单的集合。