I'm stuck on a problem while developing my back end for my Application. I run Express on my back end with Mongoose. I have a model of Users, which is like this;
const mongoose = require('mongoose');
const userSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
email: { type: String, required: true, unique: true, match: /^(([^<>()\[\]\\.,;:\s@"] (\.[^<>()\[\]\\.,;:\s@"] )*)|(". "))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9] \.) [a-zA-Z]{2,}))$/ },
username: { type: String, required: true, unique: true }, // using this one
fullName: { type: String, required: true, unique: true },
password: { type: String, required: true },
points: { type: Number, required: true }, // this one
status: { type: String, require: true }, // & this one
position: { type: String, required: true },
verficationKey: { type: String, required: true }
});
module.exports = mongoose.model('User', userSchema);
Now, I want to update ON MANY USERS the "status" and "points" keys. But for each user they might - and probably will - differ. For example lets say one user might already have 10 points and must be getting 15 and another one might have 25 and must be getting 5. I want to find my users in my DB using their "username" key (since it's unique and i can access it easily via my front end). I don't know if this is possible at all...im kinda new to express & mongo so please be patient and explain - if possible.
- I have messed around with
User.updateMany
and evenUser.find().where(...).in(...)
with the second one making some progress but could not save the users to my DB probably writing something wrong :(
- EDIT / UPDATE
Here is the code I currently found for (kind-of) run what I need. But first its a mess and secondly, its bad.
router.put('/update/points', (req, res, next) => {
User.find().where('username').in(req.body.uid)
.exec()
.then(result => {
var points = req.body.points;
result.forEach((item) => {
points.forEach((user) => {
if (item.username === user[0]) {
item.points = user[1];
item.status = user[2]
item.position = user[3];
item.save()
.then()
.catch()
}
})
})
res.status(200).json({
message: "Success"
})
})
.catch(err => {
console.log(err);
res.status(500).json({
error: err
})
})
})
This is what i came up with but im not at all satisfied. After playing with it for a couple of hours i found this "solution". But clearly its bad and inefficient.
Previous to this i did similar things. This one seems to work but i hate it.
Also a note here. In my body i send an object looking something like this from my front end;
{ "uid": ["user1", "user2", "user3"], "points": [ ["user1", 10], ["user2", 5], ["user3", 25]
] }
So with this "solution" i have no other option but to write inefficient code to my front side too.
CodePudding user response:
Is there any reason why you can't merge the uid
array and the points
array into something like this? It would make it way easier to process the data on the server.
[
{ username: "user1", points: 10, status: 8, position: 21 },
{ username: "user2", points: 6, position: 4 },
{ username: "user3", points: 9 },
...
]
Then you could do something like this on the server:
router.put('/update/points', async (req, res, next) => {
try {
for (let user of req.body.users) {
let targetUser = await User.findOne({ username: user.username });
if (targetUser) {
// Make the changes and save
targetUser.points = user.hasOwnProperty("points") ? user.points : targetUser.points;
targetUser.status = user.hasOwnProperty("status") ? user.status : targetUser.status;
targetUser.position = user.hasOwnProperty("position") ? user.position : targetUser.position;
await targetUser.save();
}
}
res.status(200).json({
message: "Success"
});
} catch(err) {
console.log(err);
res.status(500).json({
error: err
});
}
});