I have User model and every user can have an array of ownerId's. I want to make an API which will push a new ownerId to the array, but if this ownerId already exists, do nothing..
I have tried $addToSet but it doesn't work.. However it works with $push, but if ownerId already exists it keeps pushing the same ownerId so i have duplicates which is not OK..
User model
const UserSchema = new mongoose.Schema({
email: { type: String, required: true, min: 6, max: 255 },
password: { type: String, required: true, min: 4, max: 1024 },
role: { type: String, required: true, default: "User" },
owners: [
{
type: Schema.Types.ObjectId,
ref: "Owners",
required: false,
},
],
});
And my NodeJS Mongoose API:
exports.addOwnerToUser = async (req: Request, res: Response) => {
try {
let ObjectID = require("mongodb").ObjectID;
const user = {
email: req.body.email,
ownerId: req.body.ownerId,
};
const updatedUser = await User.findOneAndUpdate(
{ _id: req.params.userId },
{
$push: { owners: req.body.ownerId },
}
);
console.log(updatedUser);
res.status(201).json({ sucess: true, msg: "User updated sucessfully" });
} catch (err) {
res.status(404).json(err);
}
};
Thanks
CodePudding user response:
$push will just push data in array, in your case you should use $addToSet
$addToSet only ensures that there are no duplicate items added to the set and does not affect existing duplicate elements.
const updatedUser = await User.findOneAndUpdate({
{ _id: req.params.userId },
'ownerId.ownerId': {
'$ne': new mongoose.ObjectID(req.body.ownerId)
}
}, {
$addToSet: {
'ownerId.ownerId': new mongoose.ObjectID(req.body.ownerId)
}
}, {
new: true
});
CodePudding user response:
just remove below query
'ownerId.ownerId': {
'$ne': req.body.ownerId
}
Updated code.
const updatedUser = await User.findOneAndUpdate({
_id: req.params.userId,
}, {
$addToSet: {
'ownerId.ownerId': req.body.ownerId
}
}, {
new: true
});
OR
with ownerId Query
const updatedUser = await User.findOneAndUpdate({
_id: req.params.userId,
'ownerId.ownerId': {
'$ne': req.body.ownerId
}
}, {
$push: {
'ownerId': {ownerId: req.body.ownerId }
}
}, {
new: true
});
CodePudding user response:
Your schema design is not right, that is why $addToSet is not working for you.
so, if you want multiple owners in the user object please change your schema design to this
const UserSchema = new mongoose.Schema({
email: { type: String, required: true, min: 6, max: 255 },
password: { type: String, required: true, min: 4, max: 1024 },
role: { type: String, required: true, default: "User" },
ownerId: [{
type: Schema.Types.ObjectId,
ref: "Owners",
required: false,
}],
});
After this use $addToSet to add the new owner id in the user object it will not add the duplicates For Reference: https://www.mongodb.com/docs/manual/reference/operator/update/addToSet/
Note:
As per my previous experience with this kind of work, it is better if you change the key ownerId
to owners
because in general these are the owners array not the ownerId
CodePudding user response:
Try this:
exports.addOwnerToUser = async (req: Request, res: Response) => {
try {
let ObjectID = require("mongodb").ObjectID;
const user = {
email: req.body.email,
ownerId: req.body.ownerId,
};
const updatedUser = await User.findOne({
_id: req.params.userId
})
.then(user => {
if (user.ownerId[0]) {
user.ownerId[0].ownerId = req.body.ownerId;
}
})
console.log(updatedUser);
res.status(201).json({
sucess: true,
msg: "User updated sucessfully"
});
} catch (err) {
res.status(404).json(err);
}
};