I am creating a user experience where a user will be able to rate items from different vendors. My initial thought is for each User schema to have an array which stores all the items that the user has rated. The rated item would include the unique vendor item ID and a numerical rating value.
User Model
const userSchema = new mongoose.Schema({
...
userType: String,
ratedItems: Array,
...
});
Controller
exports.postUpdateRatedItem = (req, res, next) => {
User.findById(req.user.id, (err, user) => {
if (err) { return next(err); }
user.update(
{ $push: {ratedItems : {
vendorItem : req.body.itemID,
rating : req.body.rating
}}},
function (err) {
res.send(200);
});
});
}
Current Output
{
"_id" : ObjectId("5c91869a71ece20551fd6aed"),
"userType" : "participant",
"ratedItems" : [
{ "vendorItem" : "5c9bdd524a0dfa753e08a0a4", "rating" : "3" },
{ "vendorItem" : "5c9bdd524a0dfa753e08a0a4", "rating" : "6" }
]
}
This approach works great in adding new object to the array, but only adds and does not update. Instead, every time a user updates a rating, a new object is added to the array. What approach would allow to check for the unique vendorItem id? How do I go about checking the user rated items? If found, update the rating value, if not found, push to the array.
Thank you in advance, still learning MongoDB/Mongoose.
Edit
Below is what I expect the outcome. For each object in the array, the 'rating' is updated when the user changes the rating. The ratedItems
array will eventually have many many vendorItem
with unique IDs and ratings.
Expected Output
{
"_id" : ObjectId("5c91869a71ece20551fd6aed"),
"userType" : "participant",
"ratedItems" : [
{ "vendorItem" : "5c9bdd524a0dfa753e08a0a4", "rating" : "6" },
// additional rated items all with unique IDs
{ "vendorItem" : "5c9bcc14d5161c38a4581e28", "rating" : "2" },
{ "vendorItem" : "5c9407d143cd0f20d758acdb", "rating" : "11" }
]
}
答案 0 :(得分:0)
It sounds like you are looking for "upsert" functionality. The Mongoose model API provides findByIdAndUpdate and other similar methods for this.
Make sure you set the new
and upsert
options to true. This will create the object if it doesn't exist and return the modified document if it is updated.
Your use case would look something like this:
const update = {
$push: {
ratedItems: {
vendorItem: req.body.itemID,
rating: req.body.rating
}
}
};
const options = {'new': true, upsert: true};
User.findByIdAndUpdate(req.user.id, update, options, function(err, user) {
// ...
});