I have a complex upsert task to perform in Mongoose next to some other updates. My model looks like this:
const UserSchema = new Schema({
username: { type: String, index: true, unique: true },
email: String,
password: { type: String, select: false },
level: { type: Number, default: 0 },
highscores: [{
id: { type: Number, index: true },
stars: { type: Number },
// add a score also
}],
});
And my current database update is like this:
module.exports.addRecord = (newRecord, callback) => {
const query = { username: newRecord.username };
const update = {
$max: { level: newRecord.data.ex },
//update highscore here
};
const options = { safe: true, new: true };
User.findOneAndUpdate(query, update, options, callback);
};
I now want to upsert an object into the highscores array. So 2 situations:
- If an object doesn't have the id yet, then insert it.
- If id already exists, then update stars with the maximum between the value in the database and the incoming value in newRecord.highscores.stars.
I know how to upset and I know how to take the max, but I don't know how to combine when I need to perform I guess a $push to the highscores array. How do I do this?
Update: I managed to get it working in mongoclient, like this:
db.users.update({username: 'test', "highscores.ex": { $nin: [ 3 ]}}, {$addToSet: { "highscores": { "ex":5, "stars": 0}}})
db.users.update({username: 'test', highscores: {$elemMatch: {ex: {$in: [ 5 ] }}}}, { $max: {"highscores.$.stars":12 } });
But when I want to apply it in my model function, it will somehow not execute these operations. I'm not getting any errors.
User.update({ username: newRecord.username, 'highscores.ex': { $nin: [newRecord.highscore.ex] } }, { $addToSet: { highscores: { ex: newRecord.highscore.ex, stars: 0 } } });
User.update({ username: newRecord.username, highscores: { $elemMatch: { ex: { $in: [newRecord.highscore.ex] } } } }, { $max: { 'highscores.$.stars': newRecord.highscore.stars } });
I've noticed that when I give a callback to the first update line it will execute. But I can't give them all the callback, otherwise it will crash. What's going wrong?