Jsennin
Jsennin

Reputation: 153

MongoDB/Mongoose Updating Whole Sub/Nested Document

I have 2 schema

User Schema

const usersSchema = new schema({
    name: {
        type: String,
        required: [true, "name is required"],
        unique: true

    },
    email: {
        type: String,
        required: [true, "email is required"],
        validate: [validateEmail, 'Please fill a valid email address'],
        unique: true
    },
    password: {
        type: String,
        required: [true, "password is required"]
    },
    confirmed: {
        type: Boolean,
        default: true
    },
    (...)

});

ActiveUser Shema

const ActiveUsers = new schema({

    currentActiveUser: Users.schema,
    isInMatch: {
        type: Boolean,
        default: false
    }

});

Firstly, I create activeUser schema with nested user schema.

 var user= await Users.findOne({ $or: [{ name: req.query.nameOrEmail }, { email: req.query.nameOrEmail } ]});
await activeUsers.create({ currentActiveUser: user}, function (err) {
        if (err) res.send({ error: err.message });
});

and in my program I update main user schema not the activeUser's nested one So at some point I need to update activeUser's nested user document

that is why i created a root, which gets activeUser id(from post request) .Then, find activeUser,and then find main user schema from database by using activeUser's nested doc id .Finally , update activeUser's nested document with main user schema

root

router.post('/refreshAccountInfo', async (req, res) => {

    if (!req.body.tempID.match(/^[0-9a-fA-F]{24}$/)) { res.send("invalid user"); return; }

    var currentUser = await activeUsers.findOne({ _id: req.body.tempID });

    if (!currentUser) {
        res.send("invalid user"); return;
    }

    var user = await Users.find(currentUser.currentActiveUser._id);

    await currentUser.updateOne({ "$set": { currentActiveUser: user }}, (err) => {

        if (err) console.log('error at  updating currentActiveUser\n' + err);

    });
    console.log(JSON.stringify(currentUser));
    var updatedUser = currentUser.currentActiveUser;
    var response = {
        (...)
    }
    res.send('RefreshSuccess ' + JSON.stringify(response))

});

However, It causes error.

Error

error at  updating currentActiveUser
MongoError: E11000 duplicate key error collection: 5e3fe48a014b768935d3730f_test.activeusers index: currentActiveUser.name_1 dup key: { currentActiveUser.name: null }
(node:15024) UnhandledPromiseRejectionWarning: MongoError: E11000 duplicate key error collection: 5e3fe48a014b768935d3730f_test.activeusers index: currentActiveUser.name_1 dup key: { currentActiveUser.name: null }
    at Function.create (C:\Users\Jsennin~\Documents\WordPokerServer\node_modules\mongodb\lib\core\error.js:51:12)
    at toError (C:\Users\Jsennin~\Documents\WordPokerServer\node_modules\mongodb\lib\utils.js:149:22)
    at C:\Users\Jsennin~\Documents\WordPokerServer\node_modules\mongodb\lib\operations\common_functions.js:376:39
    at handler (C:\Users\Jsennin~\Documents\WordPokerServer\node_modules\mongodb\lib\core\sdam\topology.js:913:24)
    at C:\Users\Jsennin~\Documents\WordPokerServer\node_modules\mongodb\lib\cmap\connection_pool.js:356:13
    at handleOperationResult (C:\Users\Jsennin~\Documents\WordPokerServer\node_modules\mongodb\lib\core\sdam\server.js:493:5)

I searched a lot about this, but what I found is only updating some part of nested doc (like { "$set": { "currentActiveUser.name": user.name }) but not whole nested doc. How can I update whole nested doc?

EDIT

I found my mistake which causes error. In refresh root I used var user = await Users.find(currentUser.currentActiveUser._id); which returns array of users(which is only with 1 element though), instead I should have typed findOne, that is why it was causing duplicate error since it was null.

Upvotes: 4

Views: 79

Answers (1)

Stephen Taylor
Stephen Taylor

Reputation: 868

Try this:

var user = await Users.findOne(currentUser.currentActiveUser._id);
await currentUser.replaceOne({ "_id": user.id }, { user }});

Upvotes: 1

Related Questions