未成功更新Mongoose子文档

时间:2017-03-21 18:16:17

标签: javascript node.js mongodb mongoose subdocument

我目前有一个用于Item文档的Mongoose模式,它有一个名为linkedItems的子文档。这两个定义如下:

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,
});

所有链接的项都有score属性,用于存储父Item文档与每个linkedItem之间关系的强度。我有一个函数updateLinkedItemRating,当传递新的评级时,父项ID和链接的项ID应该通过在新分数中取平均来更新链接项的分数(currentNumberOfRatings是到目前为止平均得分的评分数量)。根据我在Mongoose子文档中找到的文档,updateLinkedItemRating中的以下代码段应该更新此分数。它正确计算新分数,但数据库未正确更新,并且回调中的errresult都记录为空。任何建议将不胜感激。

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
        }
    );
});

1 个答案:

答案 0 :(得分:1)

你不应该需要findOneAndUpdate,因为你已经有了linkedItem

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

所以你可以设置这些属性,然后使用.save()

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