Mongoose subdocument update failed

I currently have a Mongoose schema for documents Item

that has a sub-document called linkedItems. These two are defined as follows:

const ItemSchema = new Schema({
    description: { type: [String], required: true },
    linkedItems: [linkedItemSchema],
});

const linkedItemSchema = new Schema({
    _id: Schema.Types.ObjectId,
    title: String,
    score: Number,
    currentNumberOfRatings: Number,
});

      

All related elements have an attribute score

that preserves the relationship between the parent document Item

and each linkedItem

. I have a function updateLinkedItemRating

that when passing in a new rating, parent ID and related item ID, it should update the rating of the related item by averaging over the new rating ( currentNumberOfRatings

this is the number of ratings that have been averaged in the score so far). The following code snippet inside updateLinkedItemRating

should update this score based on the documentation I found in the Mongoose sub-pages. He correctly calculates the new point, but the database is not updated properly, and both err

and result

callback registered as null. Any suggestions would be appreciated.

Item.findOne({ _id: parentItemId }, function(err, item) {
    // Calculate new average score, this all works fine
    const linkedItem = item.linkedItems.id(linkedItemId);
    const currentTotalNumberOfRatings = linkedItem.currentNumberOfRatings;
    const currentScore = linkedItem.score;
    const newAverageNumerator = parseInt(currentScore) * parseInt(currentTotalNumberOfRatings) + parseInt(rating);
    const newAverageDenominator = parseInt(currentTotalNumberOfRatings) + 1;
    const newAverageScore = newAverageNumerator * 1.0 / newAverageDenominator;

    console.log(newAverageScore); // This logs the proper number
    //This does not update the DB as expected
    Item.findOneAndUpdate(
        { _id: item._id, 'linkedItems._id': linkedItemId },
        {
            $set: {
                'linkedItems.$.score': newAverageScore,
                'linkedItems.$.currentNumberOfRatings': currentTotalNumberOfRatings + 1,
            },
        },
        function (err, result) {
            console.log(err); // Logs null
            console.log(result); // Logs null
        }
    );
});

      

+3


source to share


1 answer


You don't need findOneAndUpdate as you already have an associated element when you do

const linkedItem = item.linkedItems.id(linkedItemId);

      



So you can just set these properties and then use .save ()

linkedItem.score = newAverageScore;
linkedItem.currentNumberOfRatings = currentTotalNumberOfRatings;
item.save(function(err, result){
  console.log(err);
  console.log(result);
});

      

+1


source







All Articles