2016-09-26 98 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中的简单示例开始。我更喜欢的方式是将所有数据库调用包装在模块中的承诺中,然后通过调用那些包装的方法来应用链接。承诺是伟大的,一旦你习惯了他们,可以节省你头痛。 –

相关问题