2017-03-21 60 views
3

我目前有一個Mongoose模式的Item文檔,其中有一個名爲linkedItems的子文檔。兩個的定義如下:未能成功更新Mongoose子文檔

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

'parseInt'和'* 1.0'有什麼用? –

回答

1

你不應該需要findOneAndUpdate,因爲你已經擁有的鏈接項,當你做

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

所以,你可以只設置這些屬性,然後使用.save()

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