How can I update existing mongodb database with a new array in Node js

My mongodb data is looking like this

[{"_id":"66076517c835e00d55714b41","UMKC":{"users":{"professors":[],"students":[],"admins":[]}}}]
,{"_id":"66076517c835e00d55714b41","UNT":{"users":{"professors":[],"students":[],"admins":[]}}}]]

I want to update the users accroding to their roles. The data needs to be appeneded looks like this

{
'fname':fname,
'lname':lname,
}

I tried updating it like this

router.post('/register', async (req, res) => {
    const { fname, lname, email, univName, id, role, password, _id } = req.body;
    const adminData = { fname, lname, email, id, password }
    const filter = { _id: new ObjectId(_id) }
   
    try {
        const updateResult = await Users.updateOne({filter},
            {$push:{
                'users.admins':{
                    'fname':fname,
                    'lname':lname,
                    'id':id,
                    'email':email,
                    'password':password
                }
            }}
            );console.log(updateResult)
    } catch (error) {
        console.log(error)
    }
})


I followed a thread in mongodb website

The Users model looks like this

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    id: {
        type: Number,
        required: true,
        unique: true
    },
    fname: {
        type: String,
        required: true,
        minlength: 2,
        maxlength: 50
    },
    lname: {
        type: String,
        required: true,
        minlength: 2,
        maxlength: 50
    },

    email: {
        type: String,
        required: true,
        unique: true,
        validate: {
            validator: (email) => /^[\w-\.]+@([\w-]+\.)+[a-zA-Z]{2,4}$/.test(email),
            message: 'Please enter a valid email address.'
        }
    },
    password: {
        type: String,
        required: true,
        minlength: 8
    }
});

const Users = mongoose.model('Users', userSchema);

module.exports = Users; // Export the Users model directly

The data is not being updated in the db. Is there something I am doing wrong?

EDIT:

I tried changing the variable inside the push like this

'users.admins' to 'UNT.users.admins' also `[${univName].users.admins`

just to see if it works. But no luck

Hi @Sasidhar_Mankala, Welcome,

What console log prints?

Hello,

The keys - UMKC and UNT, are to be referenced in the query. You can see a working example below.

Very important
Please do take care that the document matching the given Id has the given key.
For example, the query document { _id : 2 } will fail since there is no key UMKC in that document. The same point has been explained below.

let t = db.test;
t.find()
 {
    _id: '1',
    UMKC: {
      users: {
        professors: [],
        students: [],
        admins: [ { fname: 'somename', lastname: 'somelastname' } ]
      }
    }
  },
  {
    _id: '2',
    UNT: { users: { professors: [], students: [], admins: [] } }
  }

t.updateOne({_id: '1'}, {$push: {"UMKC.users.admins":{'fname':'somename','lastname':'somelastname'}}});

Output:
 _id: '1',
    UMKC: {
      users: {
        professors: [],
        students: [],
        admins: [ { fname: 'somename', lastname: 'somelastname' } ]
      }
    }

The keys - UMKC and UNT, would vary based on the documents. Therefore the queries also need to adjust accordingly. In the example above, it handles only one of the keys - UMKC.

Alternative schema
This need can also be addressed by adopting a minor modification in your schema. If you change this key - the varying keys - into values, it will let you query through the same single update query. It will take away the need to adjust your query according to the varying keys.

Sample document:

{
    _id: '1',
    somesubdocumentkey : {
      somekey : 'UMKC', 
      users: {
        professors: [],
        students: [],
        admins: [ ]
      }
    }
  },

Thanks
WeDoTheBest4You

1 Like