2016-09-26 92 views
0

我有以下代碼爲旨在更新Mongo中的文檔的API。它使用collection.update將值插入一個部分,然後使用另一個collection.update將這些值推送到文檔內的數組中。Mongo更新記錄與值設置在相同的查詢

但是,當我運行此代碼時,我一直收到nanevents.eventTimeevents.endDate = null。我如何修改此以正常工作?也就是說,我首先將值插入runtime.,然後使用這些值推入events陣列。

router.get('/stop/:id', function(req,res){ 
    var collection = db.get('Activity'); 

    //Important to use findOne here to get an object back instead of an array 
    collection.findOne({_id : req.params.id }, function(err, activity){ 
     if (err) throw err; 
     res.json(activity); 
     //console.log(activity); 

     collection.update({ 
      _id: activity._id 
     }, 
     { 
      $set: { 
        "runtime.started": false, 
        "runtime.endDate": new Date() 
      } 
     }, 
     function(err, activity){ 
      if (err) throw err; 
      //res.json(activity); 
      console.log(activity); 
     } 
     ); 

     collection.update({ 
      _id: activity._id 
     }, 
     { 
      $push: {events: { 
         eventTime: ((activity.runtime.endDate - activity.runtime.startDate)/1000), 
         startDate: activity.runtime.startDate, 
         endDate: activity.runtime.endDate 
        } 
       }, 
     }, 
     function(err, activity){ 
      if (err) throw err; 
      //res.json(activity); 
      console.log(activity); 
     } 
     ); 

    }); 
}); 

enter image description here

enter image description here

+0

什麼是你runtime.endDate和runtime.startDate值? – abdulbarik

+0

查看附件。 – MadPhysicist

+0

你確定減法適合你嗎? – abdulbarik

回答

1

我想無論是你應該使用承諾或嵌套的回調,JavaScript是異步的,所以即使它看起來像第二次更新的通話將第一之後被調用,在現實中他們被同時調用,因此我猜想這種奇怪的行爲。

最好把你的數據庫調用包裝好並應用鏈接。也許你想看看令人印象深刻的$ q承諾。如果你不希望使用的承諾,然後調用第一次更新調用

router.get('/stop/:id', function(req,res){ 
    var collection = db.get('Activity'); 

    //Important to use findOne here to get an object back instead of an array 
    collection.findOne({_id : req.params.id }, function(err, activity){ 
     if (err) throw err; 
     res.json(activity); 
     //console.log(activity); 

     collection.update({ 
      _id: activity._id 
     }, 
     { 
      $set: { 
        "runtime.started": false, 
        "runtime.endDate": new Date() 
      } 
     }, 
     function(err, activity){ 
      if (err) throw err; 
      //res.json(activity); 
      console.log(activity); 
      collection.update({ 
      _id: activity._id 
      }, 
      { 
      $push: {events: { 
         eventTime: ((activity.runtime.endDate - activity.runtime.startDate)/1000), 
         startDate: activity.runtime.startDate, 
         endDate: activity.runtime.endDate 
        } 
       }, 
     }, 
     function(err, activity){ 
      if (err) throw err; 
      //res.json(activity); 
      console.log(activity); 
     } 
     ); 
     } 
     ); 

    }); }); 

是的函數內的第二次更新方法看起來相當混亂,這就是爲什麼承諾都不錯。

更新,也許你可以嘗試合併兩個更新調用到一個

collection.findOne({_id : req.params.id }, function(err, activity){ 
     if (err) throw err; 
     res.json(activity); 
     //console.log(activity); 
     var date = new Date(); 
     var duration = (date - activity.runtime.startDate)/1000; 
     collection.update({ 
      _id: activity._id 
     }, 
     { 
      $set: { 
        "runtime.started": false, 
        "runtime.endDate": date 
      }, 
      $push: {events: { 
         eventTime: duration, 
         startDate: activity.runtime.startDate, 
         endDate: date 
        } 
       } 
     }, 
     function(err, activity){ 
      if (err) throw err; 
      //res.json(activity); 
      console.log(activity); 
    }); 

}); 
+0

你會如何去使用承諾?這是一種更好的方式還是僅僅是一種替代方案? – MadPhysicist

+0

此外,我昨天嘗試了類似的東西,但無濟於事。事實上,我複製了你的代碼,當我看着Mongo時,它仍然會產生'runtime.endDate = null'。 – MadPhysicist

+0

不僅好得多,它們還是任何I/O調用,數據庫或讀取文件等的首選方式,您可以從https://www.npmjs.com/package/q中的簡單示例開始。我更喜歡的方式是將所有數據庫調用包裝在模塊中的承諾中,然後通過調用那些包裝的方法來應用鏈接。承諾是偉大的,一旦你習慣了他們,可以節省你頭痛。 –

相關問題