mongoDB : updating an objects using dot notation (multi-level object)

╄→尐↘猪︶ㄣ 提交于 2019-12-12 10:11:31

问题


I have an object with the following form :

{
    "_id": ObjectId("4fa43f4d1cf26a6a8952adf1"),
    "userId": "1",
    "facebookId": "1234",
    "groups": [{
        "groupName": "testGroup",
        "members": [{
            "memberFirstName": "userFirstName",
            "memberLastName": "userLastName",
            "memberDetails": {
                "userId": "1",
                "faceBookId": "1234"
            }
        }]
    }]
}

It's a collection that holds for each user - its groups, with each group containing the group members... So the "groups" key is an array (or list), and so is the "members" key. (each user could have multiple groups, each group has multiple group members).

I'm having a hard time updating the object with a new group member, what I'm trying to do is :

db.collection.update({
    userId: "1"
}, {
    $push: {
        "groups.members": {
            membersDetails: {
                userId: "2",
                faceBookId: "54321"
            },
            memberFirstName: "UserB",
            memberLastName: "UserBLastName"
        }
    }
});

But it doesn't seem to work.

got the following error :

can't append to array using string field name [members]

I'm also trying to work with the Java driver, but that doesn't seem to work as well.

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);

回答1:


This won't work because groups is an array, but you're referencing a property in it as if it were an object. You could access things like groups.0.members or groups.1.members because these refer to specific items in the array, but the groups object itself doesn't have a members attribute to append to.

I'm not totally sure what your update needs to do exactly, but you could add a filter on groups.groupName to your query, and then do $push with groups.$.members to append a member only to the group that matched.

http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator




回答2:


It's because your user model can have multiple groups so you need to match a group in the filter and use the positional operator $ in the update. So your update would be something like this (untested):

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"
        }
    }
});

When you have an array of values, the positional operator basically says "at the position of the matched value in the array".

However, you can only do this one level of arrays deep, so you wouldn't be able to match a specific member in a specific group, for example - so you may want to break up your document into a number of simpler collections if you're going to need to do this sort of thing.



来源:https://stackoverflow.com/questions/10456325/mongodb-updating-an-objects-using-dot-notation-multi-level-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!