简体   繁体   中英

Update multiple documents in MongoDB by altering object in array

I have a simple application with registration/login and it is basically a coursera/udemy type, where the app lists specific courses and users can like them or enroll in them. I have been trying to make a mongodb function that updates a user in the database and since users can like the courses it has to update all courses too (courses have a field "usersLiked", which is an array and keep all user documents which have liked it).

The course structure is the following:

{
    "_id" : ObjectId("5977662564aac9f6c8d48884"),
    "title" : "Title",
    "lecturer" : "Lecturer",
    "length" : 30,
    "coverPhoto" : "Photo",
    "usersLiked": [ 
        {
            "_id" : ObjectId("597763e346a7a463cbb8f529"),
            "fullname" : "Name",
            "username" : "Username",
            "password" : "Hash",
            "city" : "City",
            "street" : "Street",
            "website" : "Website"
        }
    ],
    "lectures" : [ 
        {
            "title" : "Introduction",
            "number" : 1,
            "url" : "someURL"
        }
    ]
}

And the user structure:

{
    "_id" : ObjectId("597763e346a7a463cbb8f529"),
    "fullname" : "Name",
    "username" : "Username",
    "password" : "Hash",
    "enrolledCourses" : [ 
        ...
            ]
        }
    ],
    "city" : "City",
    "street" : "Street",
    "website" : "Website"
}

So now I am calling this function when I want to change. It changes the userCollection but in the courseCollection it does nothing, while it should get all courses and if some of them have an object with username(the user's username) in the "usersLiked" array it should modify the user there too.

const updateUser = (username, details) => {
        usersCollection
            .update({
                username: username,
            }, {
                $set: {
                    fullname: details.fullname,
                    city: details.city,
                    street: details.street,
                    website: details.website,
                },
            });
        coursesCollection
            .updateMany(
                {
                    usersLiked: {
                        $elemMatch: {
                            username: username,
                        },
                    },
                },
                {
                    $set: {
                        'usersLiked.username': details.username,
                        'usersLiked.city': details.city,
                        'usersLiked.street': details.street,
                        'usersLiked.website': details.website,
                    },
                }
            );
    };

Your match on the course update looks valid but you are trying to set values into an array and according to the Mongo docs you need to provide an array indexer or a positional operator.

The following will allow the set command to operate on the first element within the usersLiked array which matches the given username .

coursesCollection.updateMany(
    {
        usersLiked: {
            $elemMatch: {
                username: username,
            },
        },
    },
    {
        $set: {
            'usersLiked.$.username': details.username,
            'usersLiked.$.city': details.city,
            'usersLiked.$.street': details.street,
            'usersLiked.$.website': details.website
        },
    }
)

You could also choose which element in the usersLiked array to update eg usersLiked.1.username but I suspect each course only has one element in usersLiked for a given username in which case using the $ operator (which means: the first matching array element) should suffice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM